C语言 指针数组的问题

若有定义语句:int a[2][3],*p[3],则以下语句正确的是(C)
A)p=a B)p[0]=a C)p[0]=&a[1][2] D)p[1]=&a;
为什么不选B?a是二维数组的首地址啊,和数组第一个元素的地址不是一样的吗?为啥不可以

关注地址类型,只要类型匹配就正确,下面描述中注意括号,用来断句。

int a[2][3]
数组类型是int [2][3]。
地址类型是 int (*)[3],含义是 指向(含3个整数的一维数组)的常量指针,该指针指向的地址为3个列的一行,所以数组名本身就是行地址。

int *p[3]
数组类型是 int *[3] ,含义是 :含3个(整数指针)的数组。
地址类型是 int **,含义是:指向(整数指针)的常量指针。

A)p=a,错误
取a的地址赋值给p,p是数组,数组就是常量指针,所以不可以赋值。
B)p[0]=a,错误
p[0]是整数指针,类型是int *,和a的地址类型不匹配。
C)p[0]=&a[1][2],正确
&a[1][2]是a数组中一个整数元素的地址,类型int * 和p[0]类型匹配。
D)P[1]=&a,错误
&a就是a的地址,类型是int (*)[3],与p[1]的类型不匹配。追问

行地址的类型和整数元素的地址的类型不一样嘛

追答

当然不一样,行地址类型(指针)指明该行的列宽,就是一行有多少元素,所以类型是 int (*)[3],是二级指针,整数元素地址是指明单个元素的地址,int *, 一级指针,虽然地址的值都一样,但是类型不同。

假如指针p的类型是 int (*)[3],即如此定义: int (*p)[3]=a
那么p++后,p指向第二行,即a[1](第二行首地址)。虽然p中的地址初始值就是a[0][0]的地址,也是a的地址,也是a[0]的地址(第一行首地址),但是指针运算时的对齐宽度是4*3,就是3个int类型的宽度,也就是12个字节。所以p++后,p指向了元素a[1][0],从而实现行定位。

而如果指针p是int *,即如此定义: int * p=a[0][0];
此时p的值和上面的p的值是一样的,但是p++后,指向的是a[0][1],因为对齐宽度是1个int类型的宽度,即4字节,实现整数元素的定位。

所以指针类型不同关键在于数据对齐或叫数据定位,所以你只要了解不同指针类型的对齐宽度就可以掌握指针及数组一些经常容易混乱的概念。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-09-19
int *p[3],那么p的类型是int*[3],p是一个数组,每个元素是int*,你可以看看int a[2][3]代表int*的,有哪一个就很明白了。
第2个回答  2014-09-19
地址一样但类型不一样追问

行地址的类型和整数元素的地址的类型不一样嘛

追答

p[0]是指向整型的指针,a是指向一维整型数组的指针,&a是指向二维数组的指针
参考http://see.xidian.edu.cn/cpp/html/476.html

第3个回答  2014-09-19
a相当于一个指针p【0】存的是地址所以不行追问

行地址的类型和整数元素的地址的类型不一样嘛

相似回答