C++数组(数组定义方式、数组名作用、数组地址)


1 数组概述

数组是一个集合,用于存放相同类型的数据元素。

特点1:数组中的每个数据元素具有相同的数据类型
特点2:数组占用一段连续的内存空间


2 一维数组

2.1 一维数组定义方式

注1:数组名的命名规范与变量名命名一致,且数组名不能与变量重名。
注2:数组的下标/索引从0开始。

一维数组定义的3种方式:
(1)数据类型 数组名[ 数组长度 ];

注:定义数组时,若未给定数组元素的初始值,则必须指定初始数组长度,否则提示错误:“不允许使用不完整的类型”。

(2)数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};

注:数组初始化时,若大括号{ }内的元素个数小于定义的数组长度,则剩余数组元素默认使用 0 填充

(3)数据类型 数组名[ ] = { 值1,值2 ...};

注:定义数组元素初始值时,数组可以不指定初始数组长度。

扫描二维码关注公众号,回复: 12490888 查看本文章

示例

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 一维数组数组名

一维数组名称的作用
(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整个数组的地址【地址值相同,含义不同】。

总结
一维数组名不表示数组首元素地址的两种特例【其它情况下,数组名均表示数组首元素地址】:
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. 表示数组首元素地址,指向数组第1个元素,arr + 1&arr[0] + 1会跳过第1个元素【加上1个数组元素的字节数】,指向数组的下1个元素。
  2. arr&arr[0]的地址类型为int *类型,使用int类型的指针(指向数组首元素的指针)接收。

(2) &arr

  1. 表示整个数组的地址,指向整个数组,&arr + 1会跳过整个数组【加上整个数组的总字节数】,如int *p = (int *)(&arr + 1),指针p指向数组的末尾。
  2. &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 行的地址arrarr[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]

  1. 表示二维数组首元素地址,指向二维数组第0行第0列元素, arr[0] + 1等价于&arr[0][0] + 1会在二维数组第0行跳过第1个元素【加上1个数组元素的字节数】,指向二维数组第0行的下1个元素。
  2. arr[0]&arr[0][0]的地址类型为int *类型,使用int类型的指针(指向数组第0行首元素的指针)接收。如int *p = arr[0];int *p = &arr[0][0];

(2) arr 等价于 &arr[0]

  1. 表示二维数组第0行地址,指向整个数组,arr + 1会跳过二维数组当前行【加上二维数组每行的总字节数】,如(arr + i)&a[0] + i,指向二维数组的下 i 行
  2. arr&arr[0]的地址类型为int (*)[数组列数]类型,使用数组指针(指向数组的指针)接收。如int (*p)[4] = arr;int (*p)[4] = &arr[0];

(3) &arr

  1. 表示整个二维数组的地址,指向整个二维数组,&arr + 1会跳过整个二维数组【加上整个二维数组(共m * n个元素)的总字节数】,指向数组的末尾。
  2. &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;
}

猜你喜欢

转载自blog.csdn.net/newson92/article/details/109879873