c语言数组指针问题

int main()
{
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
printf("%x\n",a);
printf("%x\n",a+0);
printf("%x\n",&a[0][0]);
printf("%x\n",*(a+0));

int b[4]={1,2,3,4};
printf("%d\n",*(b+1));

return 0;
}

有一点问题我没弄懂:像一维数组b,b+1就是一维数组第一个元素的地址,*(b+1)就是取这个地址的值,也就是2;
但是二维数组,a+1不就是第一行的首地址吗,那么*(a+1)不就是第一行首地址对应的数据吗?但是现在为什么*(a+1)与a+1一样啊??a+1是地址,*(a+1)不应该是这个地址对应的值吗???

二维数组时,数组名a是一个一维数组指针常量,它的值是二维数组第一行(是一个一维数组)的 地址。

int a[3][4]时,a是int(*)[4]的常量类型,指向二给数组第一行。

a + 1指向二维数组的第二行,*(a + 1)得到的二维数组的第二行,是一个一维数组,也就是说*(a + 1)是int[4]类型的,把它看作 int b[4],那么*(a + 1)就相当于b。

要理解这个问题,先深度理解一下一维数组,比如int b[4],

显然b是int * const类型的,它与&b[0]一样,是数组b的首元素的地址,输出b + 1与(&b[0] +1)后发现地址值是数组b第二个元素的地址,即跳过了1个元素。

int b[4]; //假设b的地址值是10000
printf("%d",(int)(b + 1)); //32位下,输出10004,即跳了4个字节

而&b,才是真正的称得上的数组的首地址,虽然它的值与b和&b[0]相等,但是它的类型是int(*)[4],是一个一维数组指针,在二维数组里也称为行指针,输出&b+1后发现,地址值是数组b最后一个元素后面的地址,即跳过了整个一维数组。

int b[4]; //假设b的地址值是10000
printf("%d",(int)(&b + 1)); //32位下,输出10016,即跳了16个字节

int(*p)[4] = &b; //声明一个数组指针指向b
printf("%d",(int)p); //输出数组指针值,就是10000
printf("%d",(int)*p); //*p是输出的是就是b的值即第一元素的值,当然还是10000.
printf("%d",**p); //两个星号,取的就是第一个元素的值了。

温馨提示:答案为网友推荐,仅供参考
相似回答