【教程】C++语言基础学习笔记(七)——Array数组

文首标志
写在前面:
如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持!


【C++语言基础学习】系列文章

第一章 《项目与程序结构》
第二章 《数据类型》
第三章 《运算符》
第四章 《流程控制》
第五章 《Vector向量》
第六章 《String字符串》
第七章 《Array数组》
第八章 《函数》
第九章 《指针》
第十章 《结构体》


文章目录

  • 【C++语言基础学习】系列文章
  • 一、一维数组
    • (一)一维数组定义方式
    • (二)一维数组数组名
    • (三)冒泡排序算法
  • 二、二维数组
    • (一)二维数组定义方式
    • (二)二维数组数组名


C++支持数组数据结构,其可以储存一个固定大小的相同类型元素的顺序集合。数组被用来储存一系列数据,但它往往被认为是一系列相同类型的变量。
数组的声明并不是声明一个个单独的变量,比如number0number1、……、number99等,而是声明一个数组变量,比如numbers,然后使用numbers[0]numbers[1]、……、numbers[99]等来代表一个个单独的变量。数组中的特定元素可以通过索引访问。
所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最好的地址对应最后一个元素。

一、一维数组

(一)一维数组定义方式

在C++中要声明一个数组,一般有三种方式。

数据类型 数组名[ 数组长度 ];// 第一种定义方式
数据类型 数组名[ 数组长度 ] = {1,2, ... };// 第二种定义方式
数据类型 数组名[] = {1,2, ... };// 第三种定义方式

以下是简单的示例。

// 第一种
int arr1[3];
arr1[0] = 10;
arr1[1] = 12;
arr1[2] = 17;
// 第二种
int arr2[3] = { 10,12,17 };
// 第三种
int arr3[] = { 10,12,17 };

第一种方式定义了一个数组arr1具有三个元素,然后逐一赋值。值得注意的是数组元素下标的引用是从0开始的。
第二种方式定义数组arr2也具有三个元素,但此方式将三个元素的值直接通过{}分别赋予。而当给元素赋值不完全时(如四个元素赋三个值),按顺序剩下的没有赋值的元素初始化值默认为0,即没有赋值完的元素用0填充。
第三种方式定义的数组arr3不需要定义数组长度,直接初始化各个元素的具体值即可。但也需要注意的是不能不初始化任何元素的值,会导致编译器检测不出这个数组的长度,以至于报错。

(二)一维数组数组名

一维数组的数组名是指数组在内存中存储的起始地址。在C语言中,声明一个一维数组时,可以将一个标识符用作数组名。例如,如果声明一个名为arr的一维整型数组,那么arr就是该数组的数组名。
总结来说,一维数组名称的用途有两个。

  1. 可以统计整个数组在内存中的长度
  2. 可以获取数组在内存中的首地址

统计占用内存的长度也是使用sizeof()来查看。

int arr[3] = { 1,3,5 };
cout << "整个数组占用内存空间为:" << sizeof(arr) << endl;
cout << "每个元素占用内存空间为:" << sizeof(arr[0]) << endl;
cout << "数组中的元素个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;

返回结果如下。

整个数组占用内存空间为:12
每个元素占用内存空间为:4
数组中的元素个数为:3

而获取数组首地址直接输出数组即可。

int arr[3] = { 1,3,5 };
cout << "数组首地址(十六进制)为:" << arr << endl;// 十六进制
cout << "数组首地址(十进制)为:" << (int)arr << endl;// 十进制
cout << "数组中第一个元素地址为:" << &arr[0] << endl;

返回结果如下。

数组首地址(十六进制)为:00000018F958FB28
数组首地址(十进制)为:-111609048
数组中第一个元素地址为:00000018F958FB28

承接上一个示例,如果希望得到十六进制的首地址返回结果,直接输出数组即可;而如果希望得到十进制结果,则需要将数组转换为整型;若希望得知数组内某个元素的首地址,则需要使用取值运算符&来输出。
值得注意的是数组名是常量,不可以进行赋值操作。

(三)冒泡排序算法

冒泡排序是一种简单的排序算法,它通过依次比较相邻的元素并交换它们的位置来将一个数组按照升序或降序排列。冒泡排序的基本思想是,每一轮扫描将相邻的两个元素比较并交换位置,使得最大(或最小)的元素像气泡一样逐渐浮到数组的末尾。
简单来讲就是对数组内的元素实现了从小到大(从大到小)顺序的排列。由于结构简单,使得冒泡排序成为最常用的排序算法。
其规则如下。

  1. 从第一个元素开始,依次比较相邻的两个元素。
  2. 如果前一个元素大于(或小于)后一个元素,则交换它们的位置。
  3. 继续向后比较并交换,直到最后一个元素,这样一轮比较下来,最大(或最小)的元素就会被交换到最后。
  4. 重复执行步骤 1~3,每一轮比较都会确定一个最大(或最小)的元素的位置。
  5. 当没有发生元素交换时,排序结束。

下面是利用冒泡排序算法实现升序序列的示例。

int arr[9] = { 4,2,8,0,5,7,1,3,9 };
cout << "排序前:" << endl;
for (int i = 0; i < 9; i++)
{cout << arr[i] << " ";
}
cout << endl;

首先,定义一个乱序的数组,用循环遍历输出一下此时数组内的排序。
返回结果如下。

排序前:
4 2 8 0 5 7 1 3 9

此时回想冒泡排序算法的原理,可以得知对9个数的排列,从需要比较的第一个数字到最后一个数字其实只有8轮(第8个数字和第9个数字比较即为最后一轮),所以排序总轮数=元素个数-1;而观察可以得知,每轮对比次数=元素个数-排序轮数-1,以此规律设计冒泡排序算法。
全部代码如下。

#include "test.h"
#include <iostream>using namespace std;void test::Test()
{int arr[9] = { 4,2,8,0,5,7,1,3,9 };cout << "排序前:" << endl;for (int i = 0; i < 9; i++){cout << arr[i] << " ";}cout << endl;// 冒泡排序// 总共排序轮数=元素个数-1for (int i = 0; i < 9 - 1; i++){// 内层循环对比=每轮对比次数=元素个数-排序轮数-1for (int j = 0; j < 9 - i - 1; j++){// 如果第一个数字比第二个数字大,则交换两个数字if (arr[j] > arr[j + 1]){// 创建临时变量承载第一个位置上较大的数字int temp = arr[j];// 令第二个位置上较小的数字转移到第一个位置上arr[j] = arr[j + 1];// 令第二个位置取回原本第一个位置上那个较大的数字arr[j + 1] = temp;}}}cout << "排序后:" << endl;for (int i = 0; i < 9; i++){cout << arr[i] << " ";}cout << endl;
}

返回结果如下。

排序前:
4 2 8 0 5 7 1 3 9
排序后:
0 1 2 3 4 5 7 8 9

二、二维数组

C++支持多维数组。在 C++语言中,可以使用多维数组来存储具有多个维度的元素集合。多维数组实际上是数组的数组,每个维度都可以有自己的大小。多维数组声明的一般形式如下。

type name[size1][size2]...[sizeN];

这里主要以二维数组作为示例进行介绍。

(一)二维数组定义方式

在C++中要声明一个二维数组,一般有四种方式。

数据类型 数组名[ 行数 ][ 列数 ];// 第一种定义方式
数据类型 数组名[ 行数 ][ 列数 ] = { { 数据1,数据2 },{ 数据3,数据4 } };// 第二种定义方式
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4 };// 第三种定义方式
数据类型 数组名[][ 列数 ] = { 数据1,数据2,数据3,数据4 };// 第四种定义方式

对于第一种定义方式,test.cpp示例代码如下。

#include "test.h"
#include <iostream>using namespace std;void test::Test()
{// 第一种定义方式int arr1[2][3];arr1[0][0] = 1;arr1[0][1] = 2;arr1[0][2] = 3;arr1[1][0] = 4;arr1[1][1] = 5;arr1[1][2] = 6;// 外层循环打印行数,内层循环打印列数for (int i = 0; i < 2; i++){for (int j = 0; j < 3; j++){cout << arr1[i][j] << " ";}cout << endl;}
}

按第一种方式,定义一个2行3列的arr1二维数组,并逐个赋值,结果可以用for循环来遍历数组内容。返回结果如下。

1 2 3
4 5 6

对于第二、三、四种定义方法,承接上一个示例,test.cpp代码如下。

// 第二种定义方式
int arr2[2][3] =
{{ 1,2,3 },{ 4,5,6 }
};
// 第三种定义方式
int arr3[2][3] = { 1,2,3,4,5,6 };
// 第四种定义方式
int arr4[][3] = { 1,2,3,4,5,6 };

对于第二种定义方式,行和列的元素赋值明显,通常是最常用也是可读性最强的一种定义方式;而第三种则是在定义了行数和列数后,编译器仍能正确分类每个元素的行数和列数,从而达到预期赋值效果;第四种的原理同第三种定义方式,面对一串元素,在只有两个维度的条件下,即便仅定义了列数,编译器也能从总元素数中得出行数,从而分配赋值。需要注意的是,虽然在定义中可以省略行数,但列数却不可以省略。
代码返回结果和上一个示例相同,故不再展示。

(二)二维数组数组名

与一维数组同理,二维数组数组名也可以查看占用内存空间大小和首地址。

int arr[2][3] =
{{ 1,2,3 },{ 4,5,6 }
};
cout << "二维数组占用内存空间为:" << sizeof(arr) << endl;
cout << "二维数组第一行占用内存空间为:" << sizeof(arr[0]) << endl;
cout << "二维数组第一个元素占用内存空间为:" << sizeof(arr[0][0]) << endl;
cout << "二维数组中的行数为:" << sizeof(arr) / sizeof(arr[0]) << endl;
cout << "二维数组中的列数为:" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;
cout << "二维数组首地址(十进制)为:" << (int)arr << endl;
cout << "二维数组第一行首地址为:" << (int)arr[0] << endl;
cout << "二维数组第二行首地址为:" << (int)arr[1] << endl;
cout << "二维数组第一个元素首地址为:" << (int)&arr[0][0] << endl;
cout << "二维数组第五个元素首地址为:" << (int)&arr[1][2] << endl;

返回结果如下。

二维数组占用内存空间为:24
二维数组第一行占用内存空间为:12
二维数组第一个元素占用内存空间为:4
二维数组中的行数为:2
二维数组中的列数为:3
二维数组首地址(十进制)为:1781529192
二维数组第一行首地址为:1781529192
二维数组第二行首地址为:1781529204
二维数组第一个元素首地址为:1781529192
二维数组第五个元素首地址为:1781529212

从返回结果来看,二维数组本身、其某一行和某个具体元素之间占用的空间都是成比例的,也就是说每个元素的占用组成了二维数组行列的占用和二维数组本身的占用。对于首地址,值得注意的是二维数组本身的首地址、第一行的首地址、第一个元素的首地址是相同的;而对于第一行和第二行的首地址相差正好是第一行的占用数。


我是EC,一个永远在学习中的探索者,关注我,让我们一起进步!

文末标志

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/468267.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Protégé pizza 03 Install Protege - 本体编辑器 Ontology Editor

Protege是一款非常方便使用的开源的本体&#xff08;ontology&#xff09;编辑器&#xff0c;可以用来建立知识图谱。 这个视频介绍了Protege工具的安装&#xff0c;是学习pizza.owl系列知识的前提。 https://v.youku.com/v_show/id_XNjE1NDc0NTU3Mg.html

调用讯飞火星AI大模型WebAPI

调用讯飞火星AI大模型 记录一次调用讯飞AI大模型的过程 官方文档 首先&#xff0c;去官网申请资格&#xff0c;获得必要秘钥等 再编写url&#xff0c;该url存在编码要求&#xff0c;具体看官网url编写 具体代码如下&#xff1a; getWebsocketUrl() {return new Promise((resol…

掘根宝典之C++深复制与浅复制(复制构造函数,默认复制构造函数)

到目前为止我们已经学了构造函数&#xff0c;默认构造函数&#xff0c;析构函数&#xff1a;http://t.csdnimg.cn/EOQxx 转换函数&#xff0c;转换构造函数&#xff1a;http://t.csdnimg.cn/kiHo6 友元函数&#xff1a;http://t.csdnimg.cn/To8Tj 接下来我们来学习一个新函数…

部署JForum2过程。

居然用了两天时间&#xff0c;才把JForum2部署成功。走了一些弯路&#xff0c;主要原因是想当然&#xff0c;以为jdk和tomcat&#xff0c;应该向下兼容&#xff0c;所以就随便选的版本。 一、jdk-17、apache-tomcat-10.1.18-windows-x64&#xff0c;部署完jforum-2.8.2.war,改…

PWR电源控制

PWR电源 PWR简介 PWR&#xff08;Power Control&#xff09;电源控制 PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能 可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上…

MATLAB|【免费】高比例可再生能源电力系统的调峰成本量化与分摊模型

目录 主要内容 部分代码 结果一览 下载链接 主要内容 程序复现文献《高比例可再生能源电力系统的调峰成本量化与分摊模型》&#xff0c;从净负荷波动的角度出发&#xff0c;建立了调峰成本的量化与分摊模型&#xff0c;构造了无调峰需求的替代场景&#xff0c;将…

山东:优化提升恶劣天气高影响路段保障工作

2023年9月1日&#xff0c;山东省气象局联合省公安厅、省交通运输厅联合印发《2023年山东省恶劣天气高影响路段优化提升气象保障工作方案》&#xff08;以下简称《方案》&#xff09;&#xff0c;扎实推进恶劣天气高影响路段优化提升气象保障工作&#xff0c;为公路网安全畅通提…

scIMC:scRNA-seq插补方法基准

在scRNA-seq中一个主要的挑战即为“dropout”事件&#xff0c;它扭曲了基因表达&#xff0c;显著影响了单细胞转录组的下游分析。为了解决这个问题&#xff0c;已经做了很多努力&#xff0c;并开发了几种基于模型和基于深度学习的scRNA-seq插补方法。但是&#xff0c;目前还缺乏…

C++ //练习 6.11 编写并验证你自己的reset函数,使其作用于引用类型的参数。

C Primer&#xff08;第5版&#xff09; 练习 6.11 练习 6.11 编写并验证你自己的reset函数&#xff0c;使其作用于引用类型的参数。 #环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /**************************************…

前端秘法引言(配置vscode, 以及html的基础)

目录 一.配置环境vscode 二.配置插件 三.vscode的实用小技巧 四.标题段落换行标签 五.格式化标签 一.配置环境vscode vscode官网https://code.visualstudio.com/ 点击右上角的download 根据不同的操作系统进行下载安装,我这里选的是Windows x64 安装好后打开,点击左上角的…

sqlmap 使用笔记(kali环境)

sqlmap使用 kali环境 -u或–url 直接扫描单个路径 //如果需要登录要有cookie sqlmap -u "http://10.0.0.6:8080/vulnerabilities/sqli/?id1" --cookie"PHPSESSIDisgvp2rv4uts46jbkb9bouq6ir; securitylow"-m 文件中保存多个url&#xff0c;工具会依次扫…

Linux中signal/kill/raise/abort函数(信号函数)

signal函数&#xff1a; 函数作用&#xff1a;注册信号捕捉函数 函数原型&#xff1a; typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 函数参数&#xff1a; signum:信号编号handler:信号处理函数 测试&#xff1a;给没有读…