问一个c语言里关于多维数组地址的问题

看机械工业出版社出版的c语言程序设计(2004年1月第1版)P108中说,定义二维数组a,a代表整个二为数组的首地址,a+i代表第i行的首地址(从0行算),但P112面又有一个程序中有p<a+12,此时a+12代表a[3][4]数组后一位地址,即a+i代表内存中a后第i个地址到底哪中抒发是对的???
下面窄照书上的两条程序:
main()
{int a[3][4]={{1,3,5,7,}{9,11,13,15}{17,19,21,23}},i;
for(i=0;i<3;i++)
printf("%p",a+i);}

main()
{int a[3][4]={{1,3,5,7,}{9,11,13,15}{17,19,21,23}};
int*p:
for(p=a;p<a+12;p++)
printf(%d,*p);}

2个都不对...

首先是书写错误
int a[3][4]={{1,3,5,7,}{9,11,13,15}{17,19,21,23}};
应该写为:
int a[3][4]={{1,3,5,7,},{9,11,13,15},{17,19,21,23}};

再看下内存排列顺序:
1
3
5
7
9
11
13
15
17
19
21
23
地址从低到高、

for(i=0;i<3;i++)
这个取的数分别为:a[0],a[1],a[2]没有后面的第二唯数组

for(p=a;p<a+12;p++)
这个首先提示指针类型不符合、p=a错误、
你可以用sizeof来测试一下a的大小、GCC编译器a的大小是3*4*4字节=48
这说明初始化的时候a不仅仅保存的是数组的起始位置、还有全部元素的起始位置、所以不可以将a赋给p(仅仅是在语法上)这句最后导致访问非法内存、因为内部一共循环了48次、很显然这段代码是错误的...

以上采用编译器为GCC
温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-01-17
你的代码有好几处错了,想来也是你不小心打错的,我就不改了。
第一个对,a+i,a即是整个数组的首地址,也是a[0]的地址,即第一行的地址。a+i即得&a[i],为第i行的首地址。
第二个错了,p=a把a的地址赋给p。p+12才是地址后移12位。
第2个回答  2009-01-17
首先说明一下类型
a的类型为int **,是一个二级指针。a[i] = *(a + i),存储的内容为&a[i][0],因此你对i的增加,取出的都是每组的第一个元素。
p的类型为int *,每次移动只会移动一个int的位置。对于a[3][4]来说,其存储方式如下:
a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1]...
这时候应该用p=a[0];
而p指向的是a[0][0]的位置,之后的移动每次只移动一个元素的长度,即先后分别指向a[0][0],a[0][1]...从a+0一直到a+11,即a[0][0]一直到a[2][3]。
不要管指针的类型,不同类型的指针只是每次移动所走的内存长度不同而已。让它们指向地址的时候,是随便什么地址(只要能访问)都可以的,指针这个变量里面只是存了一个地址而已。

另外告诉楼上的,p移动12位就非法访问了。最多只能移动11位。
相似回答