Chinaunix

标题: 指针与数组的问题 [打印本页]

作者: shecx    时间: 2012-07-26 09:52
标题: 指针与数组的问题
如下代码打印的信息为何如此,该如何理解,编译器怎么处理呢?

int nums[2][3] = {{1, 2, 3},{4,5,6}};

printf("%x\n", *(nums + 1));    // 打印的是{4,5,6}的地址
printf("%x\n", *nums[1]);        // 打印的是 4 元素的值
printf("%x\n", (*nums)[1]);      // 打印的是 2 元素的值

主要的问题是 nums[1] 在编译的时候不是变成 nums + 1 吗,即第一个打印语句与第二个打印语句应是相同的
作者: bruceteen    时间: 2012-07-26 10:53
nums + 1 时 nums需要先降为指针,即 int (*)[3],所以 nums+1 为指向 {4,5,6} 的 int (*)[3]

nums[1] 为 {4,5,6},前面加个*号,不就是4嘛(还是数组降为指针)

*nums 为 {1,2,3},后面加个[1],不就是2嘛
作者: pmerofc    时间: 2012-07-26 11:24
提示: 作者被禁止或删除 内容自动屏蔽
作者: shecx    时间: 2012-07-26 11:33
回复 2# bruceteen
nums + 1 时 nums需要先降为指针,即 int (*)[3],所以 nums+1 为指向 {4,5,6} 的 int (*)[3]

nums[1] 为 {4,5,6},前面加个*号,不就是4嘛(还是数组降为指针)

*nums 为 {1,2,3},后面加个[1],不就是2嘛


也就是说nums + 1是一个指向3个元素的数组指针,因此 *(nums + 1) 为 {4, 5, 6},即[4,5,6]数组的地址,所以输出是地址,
nums[1]为 {4, 5, 6},即[4,5,6]数组的地址,固*nums[1]为4

我这样理解应该是对的吧?

只是我有个疑问,上面的理解是从C的指针知识来分析的
我就是不理解 nums + 1 与 nums[1] 编译器是如何区分这两种情况的,nums[1]编译器不是将下标作为偏移量处理吗,即变成
nums + 1 ?
作者: shecx    时间: 2012-07-26 11:48
弄明白了,主要是感觉int num[3]的num与&num的区别比较容易弄乱自已,谢谢各位
作者: jerrymy    时间: 2012-07-27 09:45
本帖最后由 jerrymy 于 2012-07-27 09:52 编辑

括号的优先级。

(*nums)[1] 先间接引用,对于二位数组,数组名的值是第一个元素的地址,所以*nums指向{1,2,3}的第一个元素,所以(*nums)[1]是第二个值。

*nums[1],从右向左结合,[]优先级高,所以先执行nums[1],此时nums指向{4,5,6},再间接引用指针即是第一个元素4。

《C和指针》讲的很详细。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2