要回答你的这个问题,不妨先根据你的问题先编写一段小的示例程序:
#include
#include
using namespace std;
int a[3][4];
int main(){
memset(a,-1,sizeof(a));
int i;
for( i = 0; i < 3; i++){
printf(&a[i][0] = %d\n,&a[i][0]);
printf(a + i = %d; *(a + i) = %d;\n,a + i,*( a + i));
printf(a[i] = %d; &a[i] = %d;\n,a[i],&a[i]);
printf(\n);
}
}
这段示例程序在我本地上运行的结果为:
&a[i][0] = 4214816
a + i = 4214816; *(a + i) = 4214816;
a[i] = 4214816; &a[i] = 4214816;
&a[i][0] = 4214832
a + i = 4214832; *(a + i) = 4214832;
a[i] = 4214832; &a[i] = 4214832;
&a[i][0] = 4214848
a + i = 4214848; *(a + i) = 4214848;
a[i] = 4214848; &a[i] = 4214848;
我想看到这个运行结果,你已经有所了解了,下面我再详细说一下:
指针量a作为一个二维数组的指针量,其本质是一个“指向指针的指针”(为了方便,下面称其为双重指针),或者你可以理解为a为int**类型的指针量.当a做加减运算时,得到的结果仍然是一个“双重指针”,即a + i是一个双重指针,它是一个指向了原数组第i行的起始位置的双重指针.
而*(a + i)原来的双重指针解引用后得到的一个指针变量,他是一个指向了原数组第i行的起始位置的“单重指针”.
可以看出,a + i和*(a + i)尽管数据类型不同(前者为双重指针,后者为单重指针),但是他们指向同一块内存地址,因此作为指针量,他们的值是相等的.注意,仅仅是说,他们的值在数学上是相等的,并非说“他们是等价的”.
你的第二个问题亦是同理:
首先,[]作为C语言的操作符,本身即具有“解引用”的语义.明白的说,就是a[i]与*(a + i)是完全等价的,而&a[i]即等价于a + i.由于易知a + i和*(a + i)在数值上相当,那么进行等价带花可以知道,&a[i]和a[i]在数值上相等.当然,此处仍非等价关系.
至于指向行的指针,所指的就是指向行首位置的指针量.
至于你的最后一个问题,正如我刚才一直强调的那样,等号两端仅仅是数值上的相等,而非等价关系,因此无法按照你所设想的方式进行归纳推导.