C++二维数组和指针的关系
借鉴了点击打开链接和点击打开链接,并部分修改。
再翻开C++ primer时,不禁感叹此书的严谨细致。再学习下数组和指针。主要讲解二维数组和指针的对应关系。
扫盲+复习:
数组是一种复合数据类型,对数据类型,必然要介绍定义和初始化。
定义和初始化:数组的维数必须用值大于等于1的常量表达式定义。此常量表达式只能包含整型字面值常量、枚举常量货用常量表达式初始化的整型const对象。非const变量及要到运行阶段才知道其值的const变量都不能用于定义数组的维数。显示初始化的数组不需要指定其维数值。没有引用类型的数组。
对初始化说两句:函数体外定义的内置数组类型,元素初始化为0;体内定义无初始化。元素类型为类类型时,默认构造函数初始化,无默认构造函数,则必须显示初始化,与数组定义位置无关。字符数组用字符串字面值初始化时,注意字符串字面值包含一个额外的空字符。再叨叨一句指针:理解指针声明语句时,请从右往左阅读。
//以下是本文介绍的重点:
数组名----二维数组的存储----指针和二维数组的关系-----指针和数组的转换关系深入讲解
一、先说说数组名,数组名代表数组第一个元素的指针。对一维数组,数组名就代表首元素地址;对二维数组,因其元素是数组,所以数组名代表首个行地址。
对二维数组a,区分下a和a[0]:
a代表首个行地址,它的每个元素都是一个行数组,因此,它的指针移动单位是“行”。使用a[0]是把二维数组看做一个一维数组来处理,即它的元素不再是行,而是单个数组元素。所以它指向的是数组的首个元素,它的指针移动单位是“单个数组元素”。
二、二维数组在内存中如何存储:
int a[2][3]={1,2,3,4,5,6};
int m=a[0][5];//m=6
所以C++的数组在内存中是没有维数的概念的。二维数组存储时,是按照先行后列的顺序依次存储的。把每行看做一个整体,即视为一个大的数组元素。
三、指针和二维数组的对应关系:
1) 指针对应的二维数组元素地址:
int a[2][3]={1,2,3,4,5,6};
int* p=a[0];
int m=*(p+3);//m=4 即若有p=a[0](a是二维数组),则p+j指向a[0][j]。
2) 二维数组元素地址对应的指针:
int a[2][3]={1,2,3,4,5,6};
int* p=a[0];
a[i][j]=*(p+i*列数+j);或a[i][j]=p[i*列数+j];
3) 二维数组名和二维数组元素的对应关系:
用二维数组名作地址表示数组元素:二维数组a表示行元素,a+i表示第i个行元素。所以a [i] [j]用数组名表示为:*(*(a+i)+j)
4) 行数组指针:
int a[2][3]={1,2,3,4,5,6};
int** p=a;//编译错误
可以通过定义数组指针的方式,使得一个指针变量与二维数组名具有相同的性质。定义方法:int (*p)[4]=a;
区分数组指针和指针数组:数组指针是指向数组首元素的地址的指针,其本质为指针,定义为:int (*ptr_array) [10];。指针数组是数组元素为指针的数组,其本质为数组,定义为:int *ptr_array[10];。
四、深入讲解:
void function(int**array,int width,int height)
然后我们定义了一个二维数组 intp[3][3]={{1,2,3},{4,5,6},{7,8,9}};
当我们调用function时,即function(p,3,3),编译器会报错:
error C2664:'function' : cannot convert parameter 1 from int [3][3]' to int **'
数组名和指针还是有区别的。C++支持数组自动转为指针类型,但指针无法自动转换为数组类型,转换是基于从外层到内层的顺序开始转换,外层相同不再转换。
这儿为了方便讲解,先说个关系:把指针的数组认为是数组嵌套在指针外层,C++支持的转换只能从外层至内层的顺序转换,若外层相同不转换。所以,array(指针的指针)和p(数组的首元素地址,即数组首元素的指针)不能转换为同一类型。对数组指针和指针数组:指针数组可转为指针的指针,指针的指针与数组指针不同。用代码表示即:
int a[2][3];
int (*p)[2]=a;// 这个没转换,p是数组的指针,a也是
int *arr[3];
int **q=arr;//arr是指针数组,转为指针的指针
补充:软件开发 , C++ ,