C++中,int (*p)[2]和int a[1][2]怎么会是一个类型呢?
inta[1][2]={1,2};intb[2]={1,2};int(*p)[2];p=a;//这里为什么能这样赋值呢?二维数组名a和一位数组名b的类型有那里不一样吗?区...
int a[1][2]={1, 2};
int b[2]={1,2};
int (*p)[2];
p = a;//这里为什么能这样赋值呢?二维数组名a和一位数组名b的类型有那里不一样吗?区别是什么啊?
为什么int * p=a就错,int * p=b就可以呢? 展开
int b[2]={1,2};
int (*p)[2];
p = a;//这里为什么能这样赋值呢?二维数组名a和一位数组名b的类型有那里不一样吗?区别是什么啊?
为什么int * p=a就错,int * p=b就可以呢? 展开
2个回答
展开全部
int b[2]是一维数组,其地址类型是 int *
int a[1][2]是二维数组,其地址类型是 int (*)[2]
凡是数组指针都涉及一个概念,那就是元素对齐和列对齐。
什么是元素对齐?
int b[2]定义了一个一维数组,该数组每个元素类型是int,而一个int数据占用内存4字节(32位系统),也就是说元素是有宽度的,单位是字节。为使指针运算时可以准确定位每个元素,编译器必须知道每个元素的字节宽度。
比如 int *p=b;
p获得了b的地址,p++后,由于知道元素类型是int,因此每递增一个地址,实际上递增了4字节,从而实现准确定位,这就是元素对齐,而4就是int类型元素的对齐宽度。
编译器会自动为你定义的数组指定一个地址类型(隐式转换)。所以你定义的数组int b[2]的地址类型被转换为int *。而元素个数被忽略,因为指针的目的就是指向准确的元素,编译器不会检查是否越界。
列对齐
int a[1][2]告诉编译器,这是个二维数组,且每行具有2个int类元素,每行递增字节宽度就是4*2,即int类型的宽度与列数的乘积,等于每行总字节数,以便于指针在递增时可以准确定位到下一行,这就是列对齐。
因此编译器在转换时保留了列数和元素类型 int,[2],而行数[1]被忽略,就像一维数组一样忽略了行数,因为二维数组指针运算主要就是准确定位行首地址,不会检查行越界。因此最终被转换成 int (*)[2],(*)[2]意思为对齐宽度为2个元素的指针,而元素类型是int,所以int (*)[2]意思为这是一个对齐宽度为2个int类型元素的指针。
所以 p=a可以,int *p=a不可以,因为类型不匹配,而int *p=b可以,因为数组b的地址类型为int *,类型匹配 。
int a[1][2]是二维数组,其地址类型是 int (*)[2]
凡是数组指针都涉及一个概念,那就是元素对齐和列对齐。
什么是元素对齐?
int b[2]定义了一个一维数组,该数组每个元素类型是int,而一个int数据占用内存4字节(32位系统),也就是说元素是有宽度的,单位是字节。为使指针运算时可以准确定位每个元素,编译器必须知道每个元素的字节宽度。
比如 int *p=b;
p获得了b的地址,p++后,由于知道元素类型是int,因此每递增一个地址,实际上递增了4字节,从而实现准确定位,这就是元素对齐,而4就是int类型元素的对齐宽度。
编译器会自动为你定义的数组指定一个地址类型(隐式转换)。所以你定义的数组int b[2]的地址类型被转换为int *。而元素个数被忽略,因为指针的目的就是指向准确的元素,编译器不会检查是否越界。
列对齐
int a[1][2]告诉编译器,这是个二维数组,且每行具有2个int类元素,每行递增字节宽度就是4*2,即int类型的宽度与列数的乘积,等于每行总字节数,以便于指针在递增时可以准确定位到下一行,这就是列对齐。
因此编译器在转换时保留了列数和元素类型 int,[2],而行数[1]被忽略,就像一维数组一样忽略了行数,因为二维数组指针运算主要就是准确定位行首地址,不会检查行越界。因此最终被转换成 int (*)[2],(*)[2]意思为对齐宽度为2个元素的指针,而元素类型是int,所以int (*)[2]意思为这是一个对齐宽度为2个int类型元素的指针。
所以 p=a可以,int *p=a不可以,因为类型不匹配,而int *p=b可以,因为数组b的地址类型为int *,类型匹配 。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询