C++数组(数组定义方式、数组名作用、数组地址)
文章目录
1 数组概述
数组是一个集合,用于存放相同类型的数据元素。
特点1:数组中的每个数据元素具有相同的数据类型。
特点2:数组占用一段连续的内存空间。
2 一维数组
2.1 一维数组定义方式
注1:数组名的命名规范与变量名命名一致,且数组名不能与变量重名。
注2:数组的下标/索引从0
开始。
一维数组定义的3种方式:
(1)数据类型 数组名[ 数组长度 ];
注:定义数组时,若未给定数组元素的初始值,则必须指定
初始数组长度
,否则提示错误:“不允许使用不完整的类型”。
(2)数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
注:数组初始化时,若大括号{ }内的元素个数小于定义的数组长度,则剩余数组元素
默认使用 0 填充
。
(3)数据类型 数组名[ ] = { 值1,值2 ...};
注:定义数组元素初始值时,数组可以不指定初始数组长度。
示例:
int main() {
//定义方式1:数据类型 数组名[元素个数];
int arr[10];
//使用数组下标对数组元素进行赋值或访问
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
//定义方式2:数据类型 数组名[元素个数] = {值1,值2 ,值3 ...};
//若大括号{ }内的元素个数小于定义的数组长度,则剩余数据默认使用0填充
int arr2[10] = { 100,90,80,70,60,50,40,30,20,10 };
//定义方式3:
//数据类型 数组名[] = {值1,值2 ,值3 ...};
int arr3[] = { 100,90,80,70,60,50,40,30,20,10 };
return 0;
}
2.2 一维数组数组名
2.2.1 一维数组名称的作用
(1)统计整个数组的长度,例:sizeof(arr) / sizeof(arr[0]);
数组占用内存空间大小:
sizeof(arr)
数组单个元素占用内存空间大小:sizeof(arr[0])
数组长度:sizeof(arr) / sizeof(arr[0])
(2)获取数组在内存中的首地址,例:arr。
获取数组首地址:
arr
或&arr[0]
。
注:
arr
或&arr[0]
:数组首元素的地址 ;
&arr
:整个数组的地址【地址值相同,含义不同】。
2.2.2 一维数组名的2种特例情况
一维数组名不表示数组首元素地址的两种特例:
①sizeof(数组名)
:整个数组的大小;
②&数组名
:整个数组的地址(地址值与首元素地址相同,但意义不同),表示数组指针。
注:其它情况下,一维数组的数组名均表示数组首元素地址,等价于相应的指针类型。
示例:
int main() {
//数组名用途
//1、获取整个数组占用内存空间大小
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
cout << "整个数组所占内存空间为: " << sizeof(arr) << endl;
cout << "每个元素所占内存空间为: " << sizeof(arr[0]) << endl;
cout << "数组的元素个数为: " << sizeof(arr) / sizeof(arr[0]) << endl;
//2、获取到数组首地址
cout << "数组首地址为: " << (int)arr << endl; //17431292
cout << "数组中第一个元素地址为: " << (int)&arr[0] << endl; //17431292
cout << "数组中第二个元素地址为: " << (int)&arr[1] << endl; //17431296
//arr = 10; //错误:数组名是常量,不可赋值
return 0;
}
注1:数组名是常量,不能进行赋值,否则报错:表达式必须是可修改的左值。
注2:对数组名使用sizeof,可获取整个数组占内存空间的大小。
2.3 一维数组的地址
【以整型一维数组int arr[n]
为例】
(1) arr
等价于 &arr[0]
- 表示数组首元素地址,指向数组第1个元素,
arr + 1
或&arr[0] + 1
会跳过第1个元素【加上1个数组元素的字节数】,指向数组的下1个元素。 arr
或&arr[0]
的地址类型为int *
类型,使用int类型的指针(指向数组首元素的指针)接收。
(2) &arr
- 表示整个数组的地址,指向整个数组,
&arr + 1
会跳过整个数组【加上整个数组的总字节数】,如int *p = (int *)(&arr + 1)
,指针p指向数组的末尾。 &arr
的地址类型为int (*)[数组长度]
类型,使用数组指针(指向数组的指针)接收。
示例:
#include <iostream>
using namespace std;
int main() {
//一维数组
int arr[5] = { 1,2,3,4,5 };
/* 一维数组的地址与指针 */
int* p1 = (int *)(&arr + 1); //&arr:整个数组的地址 //&arr + 1:指向数组的末尾处
int* p2 = (int*)(arr + 1); //arr等价于&arr[0],类型为int *类型:数组首元素地址
cout << p1[-2] << endl; //4
cout << *p2 << endl; //2
cout << arr << endl; //009DFBB8
cout << *arr << endl; //1【第1个元素值】
cout << arr + 1 << endl; //009DFBBC 后移4字节【跳过1个元素】
cout << *(arr + 1) << endl; //2【第2个元素值】
cout << &arr[0] << endl; //009DFBB8
cout << *(&arr[0]) << endl; //1【第1个元素值】
cout << &arr[0] + 1 << endl; //009DFBBC 后移4字节【跳过1个元素】
cout << *(&arr[0] + 1) << endl; //2【第2个元素值】
cout << &arr << endl; //009DFBB8
cout << *(&arr) << endl; //009DFBB8
cout << &arr + 1 << endl; //009DFBCC 后移4*5=20字节【跳过整个数组】
cout << *(&arr + 1) << endl; //009DFBCC
return 0;
}
2.4 冒泡排序
作用: 常用的排序算法,对数组内元素进行排序,时间复杂度O(n2)。
步骤:
(1)比较相邻元素:若前一个元素大于后一个元素,则交换两元素;
(2)针对每一对相邻元素重复执行步骤(1),执行完毕后,最大值置于数组的最末尾;
(3)重复以上步骤,每次比较的次数减少1次,直至不再需要比较。
示例: 使用冒泡排序对数组 { 4,2,8,0,5,7,1,3,9 } 进行升序排序。
int main() {
int arr[] = {4,2,8,0,5,7,1,3,9};
int len = sizeof(arr) / sizeof(arr[0]); //数组长度
int temp;
//外层循环:每轮对比的次数
for (int i = 0; i < len - 1; i++) {
//内层循环:进行比较的元素的索引位置
for (int j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
cout << "升序排序后的数组为" << endl;
for (int i = 0; i < len; i++) {
cout << arr[i] << " ";
}
return 0;
}
3 二维数组
二维数组的每个元素均为一个一维数组,可用矩阵的形式表示。
3.1 二维数组定义方式
二维数组定义的4种方式:
(1)数据类型 数组名[ 行数 ][ 列数 ];
(2)数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2} ,{数据3,数据4} };
(3)数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
(4)数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
注1:第(2)种定义方式更直观,可提高代码的可读性;第(3)、(4)种根据二维数组的列数推断数组元素(可省略行数,不可省略列数)。
注2:定义二维数组时,若已初始化数据,则可以省略行数。
示例:
int main() {
int arr[2][3] = { {1,2,3},{4,5,6} };
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
for (int j = 0; j < sizeof(arr[i]) / sizeof(arr[i][0]); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
3.2 二维数组数组名
二维数组名称的作用:
(1)计算二维数组所占内存空间
二维数组占用内存空间大小:
sizeof(arr)
二维数组第 i 行占用内存空间大小:sizeof(arr[i])
二维数组某个元素占用内存空间大小:sizeof(arr[i][j])
(2)计算二维数组的行数与列数
二维数组的行数:
sizeof(arr) / sizeof(arr[0])
二维数组的列数:sizeof(arr[0]) / sizeof(arr[0][0])
(3)获取二维数组的首地址
二维数组首地址:
arr[0]
或&arr[0][0]
二维数组第1个元素的地址:arr[0]
或&arr[0][0]
二维数组第 0 行的地址:arr
或arr[0]
或arr + 0
【或*(arr + 0)
】
二维数组第 i 行的地址:arr[i]
或arr + i
【或*(arr + i)
或&a[0] + i
】
注:
arr[0]
或&arr[0][0]
:二维数组首元素的地址 ;
二维数组名arr
:二维数组第0行(首行)的地址,等价于arr[0]
或arr + 0
(4)二维数组的其它地址
二维数组第 i 行首元素的地址:
arr[i]
或arr + i
或*(arr + i)
或&a[0] + i
二维数组第 i 行第 j 列元素的地址:&arr[i][j]
或*(arr + i) + j
(5)通过指针解引用访问或操作某元素:*(*(arr + i) + j)
示例:
int main() {
int arr[2][3] = { {1,2,3},{4,5,6} };
//二维数组占用的内存空间
cout << "二维数组大小: " << sizeof(arr) << endl; //24
cout << "二维数组一行大小: " << sizeof(arr[0]) << endl; //12
cout << "二维数组元素大小: " << sizeof(arr[0][0]) << endl; //3
//二维数组的行数与列数
cout << "二维数组行数: " << sizeof(arr) / sizeof(arr[0]) << endl; //2
cout << "二维数组列数: " << sizeof(arr[0]) / sizeof(arr[0][0]) << endl; //3
//地址
cout << "二维数组首行地址:" << (int)arr << endl; //16053988
cout << "二维数组第一行地址:" << (int)arr[0] << endl; //16053988
cout << "二维数组第一个元素地址:" << (int)&arr[0][0] << endl; //16053988
cout << "二维数组第二行地址:" << (int)arr[1] << endl; //16054000
cout << "二维数组第二个元素地址:" << (int)&arr[0][1] << endl; //16053992
system("pause");
return 0;
}
2.3 二维数组的地址
【以整型二维数组int arr[m][n]
为例】
(1) arr[0]
等价于 &arr[0][0]
- 表示二维数组首元素地址,指向二维数组第0行第0列元素,
arr[0] + 1
等价于&arr[0][0] + 1
会在二维数组第0行跳过第1个元素【加上1个数组元素的字节数】,指向二维数组第0行的下1个元素。 arr[0]
或&arr[0][0]
的地址类型为int *
类型,使用int类型的指针(指向数组第0行首元素的指针)接收。如int *p = arr[0];
或int *p = &arr[0][0];
。
(2) arr
等价于 &arr[0]
- 表示二维数组第0行地址,指向整个数组,
arr + 1
会跳过二维数组当前行【加上二维数组每行的总字节数】,如(arr + i)
或&a[0] + i
,指向二维数组的下 i 行。 arr
或&arr[0]
的地址类型为int (*)[数组列数]
类型,使用数组指针(指向数组的指针)接收。如int (*p)[4] = arr;
或int (*p)[4] = &arr[0];
。
(3) &arr
- 表示整个二维数组的地址,指向整个二维数组,
&arr + 1
会跳过整个二维数组【加上整个二维数组(共m * n个元素)的总字节数】,指向数组的末尾。 &arr
的地址类型为int (*)[数组行数][数组列数]
类型,使用二维数组指针(指向数组的指针)接收。如int (*p)[3][4] = &arr;
。
示例:
#include <iostream>
using namespace std;
int main() {
//二维数组3行4列
int arr[3][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
cout << &arr << endl; //00DAFB34 //整个二维数组的地址
cout << &arr + 1 << endl; //00DAFB64 /后移4*3*4=48字节【跳过整个二维数组的全部12个元素】
cout << arr << endl; //00DAFB34 //二维数组第0行的地址
cout << arr + 1 << endl; //00DAFB44 后移4*4=16字节【跳过二维数组1行共4个元素】
cout << arr[1] << endl; //00DAFB44 后移4*4=16字节【跳过二维数组1行共4个元素】
cout << &arr[0] + 1 << endl; //00DAFB44 后移4*4=16字节【跳过二维数组1行共4个元素】
cout << *(arr + 1) << endl; //00DAFB44 //二维数组第1行首元素的地址
cout << *(arr + 1) + 1 << endl; //00DAFB48 后移4字节【跳过1个元素】
cout << arr[0] << endl; //00DAFB34 //二维数组首元素地址
cout << arr[0] + 1 << endl; //00DAFB38 后移4字节【跳过1个元素】
cout << &arr[0][0] << endl; //00DAFB34 //二维数组首元素地址
cout << &arr[0][0] + 1 << endl; //00DAFB38 后移4字节【跳过1个元素】
/* 数组指针,指向数组长度为4的int数组 */
//arr或&arr[0]:地址类型int(*)[4]
int (*p1)[4] = arr; //正确
int (*p2)[4] = &arr[0]; //正确
//&arr:地址类型int(*)[3][4]
int(*p)[3][4] = &arr; //正确
return 0;
}
更多推荐
所有评论(0)