c语言数组与指针相关问题,谢谢

程序如下
int a[3][2] = { 1, 3, 4, 7, 8, 2 };
int (*p)[2] = a;
printf("%x\n", p[1]);//对应a[0]的地址,
printf("%x\n", p+1);//对应a[0]的地址,
printf("%x\n", *p[1]+1);//对应a[0]的地址,
printf("%x\n", *(p+1)+1);//对应a[0]的地址,

打印结果如图
我不明白的是,前两个一样,说明p[1]和p+1都是表示一个地址。然后下边我都用*号把地址取出来,然后再加1应该都是34f9ac这个地址啊,为什么第三个却是5呢(为什么是把4取了出来再加1了呢)?为什么呢?谢谢

第1个回答  2015-12-04
注意操作符的优先级,第三个*p[1]+1中[]最高,所以是p[1]即为34f9a8,再是*指针取内容操作符,即取出地址34f9a8的内容即为4,再+1所以得到5追问

但是p+1也是34f9a8,然后我用括号括起来再取值*(p+1)也就相当于把34f9a8的内容取出来啊,为什么不是5呢?

本回答被网友采纳
第2个回答  2015-12-04
*p[1] 相当于 p[1][0], 值为4, 加上1就是5了追问

请根据我的疑问回答,我说了打印p[1]和p+1都是同一个地址,然后我都进行取值运算,然后再加1,为什么结果不一样?谢谢

追答

中括号运算会解掉一层数组, p[1]的类型为 int *(一维指针)
p本身的类型为 int **, 所以p+1所得结果也是int**(二维指针)
*号运算同中括号一样,解掉一层数组(或者维度), 所以第三行最终类型为int, 而第四行的为int *
因此三行为数字5, 而四行为一个地址

追问

那按照您的的意思p[1]是一维指针,p+1二维指针,那么其打印结果应该不一样啊,那么为什么第一行和第二行结果一样呢?

追答

一维指针的地址和二维指针的地址 的值没有规定不可以一样
不管是几维的指针, 他们的都是地址, 实际上都是一个long整形, 只不过他们在不同维度上含义是不一样的
更正一个错误, 你代码注释里应该是a[1]不是a[0]
p的正规类型为 int(*)[2], 也就是说p[0]和p[1]都是指向了一个长度为2的一维int数组的指针
而p是指向了 长度为2的"指向了长度为2的一维int数组的指针"的数组
p+1就是在p的基础上, 向后跳一个长度为2的int数组的长度, 也就是两个int的长度, 他的值表示了一个"指向了长度为2的一维int数组的指针"的数组的第二个元素的地址
所以p+1并不是a[1]的值, 而是a[1]所在的地址, 但是a[1]和a[1]所在的地址又是一样的,所以输出的内容都是同一个地址
这个东西有点绕, 简单的看 *(p+1) 和p+1是不同的两个指针(含义不同),但是他们的值恰好相同

本回答被提问者采纳
相似回答