楼主问的是一个对初学者来说,C语言指针部分最有难度的一个问题。我大概解释一下:
1、二维数组名称的本质就是一个行指针,不过它是常量;
2、行指针与二维数组名称的“指类”一致(这一点请去看看优酷上朱洪老师的指针与数组的视频)。
请尝试如下代码,注意观察输出结果:
double a[3][10], (*p)[10];
p = a;
printf("%p %p\n", a, p);
printf("%p %p\n", a+1, p+1);
printf("%p %p\n", a[2], p[2]);
printf("%p %p\n", &a[2][0], p[2]);
printf("%p %p\n", &a[2][3], p[2]+3);
观察输出结果,可以得到如下结论:
p指针+1和a+1都会移动80B(其实,这就是p被称为“行指针”的原因)
行指针,按中国词法,左偏右正(即,左边是限定词,右边是核心词),可以认为是“指向一行的指针”,完整的说是:以一行,即,一个一维数组,为基本元素的指针。对这个指针加1,将使得指针向后移动整个一维数组的空间。
按朱老师的说法:这个指针的指类为double[10];指针+1将向后移动一个指类元素的空间,即,要移动80B。
这样,p+i,将指向a数组的下标为i的那一行首地址(其实a也是一样)
另外,p是一个行指针,俗称指针的指针(严格意义上,这样称呼行指针是错误的。)
而*运算符(指向运算符)具有“指针降阶”的作用。意思是,对于二维指针,进行一次指向运算,其结果将是一个一维指针;对于一维指针变量,进行一次指向运算,其结果将是一个0维指针(实质上已经退化成一个值)。
那么,*(p+0) <=> p[0],这个p[0]或者p[i],应该这样看待:
1、p[i]的值就是&a[i][0]的值;
// &a[i][0] <=> &*(a[i] + 0) <=> a[i]
2、p[i]的指类(其所指向的内存字节空间的数据类型),是double类型;这意味着p[i] + 1将比p[i]的值大8B。
p[i] + j将指向a[i]这一行的下标为j的那个double类型元素;换句话说,p[i] + j的值,与&a[i][j]的值是一样的。其实,它们的类型也是一样的。
那么,再对这个p[i] + j做“指向运算”,当然就可以得到a[i][j]这个元素了。
因此,*(p[i] + j) <=> p[i][j] <=> a[i][j]
虽然你已经结贴了,但看到你的疑问好像并没有解决,故此罗嗦。
其实我也是刚刚学完,这些都是我的老师教的,他讲得非常清楚,你有机会了可以看看他的视频(优酷里搜朱洪)。
我的这些看法,也喜欢大家、大神们多多指教。谢谢
[
本帖最后由 犬虫门心本人 于 2013-12-19 16:24 编辑 ]