c语言问题

p指向二维数组a[3][5]的首地址
*(p+1)表示的是a[0][1]还是a[1][0],为什么有些地方说是前者有些地方说是后者,请解释一下

如果是这样的代码:
int a[3][5]={{1,2,3},{4,5,6},{7,8,9}};
int *p=&a[0][0];

这里p是一个普通的指向整型指针的指针变量,那么p可以存放任意一个整型变量的地址(const的除外)

又由于数组(不管是不是多维的)在内存中实际上是线性存放的,即:
a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] a[1][0] a[1][1] a[1][2] ...
所以(p+1)就表示a[0][1]的地址,所以 *(p+1)表示的是a[0][1]

但是要是代码是这样的:
int a[3][5]={{1,2,3},{4,5,6},{7,8,9}};
int (*p)[5]=a;//&a[0]
这时候p是指向有五个元素的行指针,其具体含义就是p把数组的元素分组了,每五个元素算一组,就是说(p+1)直接指向下一组的第一个元素,就是a[1][0],要是这样的话,那*(p+1)表示的是a[1][0]

另外:
对于int (*p)[5],这个p只能指向以五个元素为一组的地址,如:
int a[3][5][5];
int (*p)[5]=&a[i][j];
其中i>=0&&i<=2 j>=0&&j<=4,因为这里&a[i][j]都是指向含有5个元素的子数组,所以这样也是对的
为什么一定要指向五个元素的指针呢,因为这告诉编译器p+1,是什么意思了:
加了1后到底指向什么位置,对于这里的例子,加1后,直接指向下一组(一组五个)元素的开头了,就是p+1 换算成加的字节数就是:p+1*5*4,5是,每组5个,4是每个元素4字节(int是4字节),而对于普通指向整型变量的指针p,p+1 换算成字节数就是 p+1*4,直接指向下一个4byte的内存。这也是为什么指针形参的函数虚实结合的数据类型要一样,要不加1,实际加的字节数不一样会导致错误,而非指针形参只要求赋值兼容即可了
温馨提示:答案为网友推荐,仅供参考
第1个回答  2008-08-26
表示的是前者,
因为电脑里面存数据,
即使是二维的表,也是当作一维来存,只是在“换行”的地方加了标识,
具体存储方式是
a[0][0]a[0][1]a[0][2]a[0][3]a[0][4]a[1][0]a[1][1]a[1][2]a[1][3]a[1][4]a[2][0]a[2][1]a[2][2]a[2][3]a[2][4]
以a[3][5]为例,

总之就像数学里面的个位和十位一样,
呃,我是这样理解的,
屡试不爽。。。
第2个回答  2008-08-26
a[3][5] 是个由数组 组成 的数组
p是个指向指针的指针

p指向a[0] 不是a[0][0] 但*p的值确实为a[0][0]的值
因为a[0]也是个指针 指向a[0][0]

所以p+1 是指向a[1]的 a[1]为a[1][0]

#include <stdio.h>

main()
{
int s[2][3]={1,2,3,4,5,6};
int (*p)[3]=s;
printf("%d\n",**p);
printf("%d",**(p+1));
getchar();

}
第3个回答  2008-08-25
#include <iostream.h>
int main()
{
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int * p=a[0];

cout<<*(p+1)<<endl;
return 0;
}
//我保存为。pt.cpp ,编译为pt.out

结果:
XXXXXXX@ubuntu-XXXXXX:~/桌面$ ./pt.out
2

PS:我用的是桌面linux系统G++编译的,而且用的是C++。不过跟在win下用C的指针效果相同。

还有这么一句。这实例很短,我相信你自己也能写出来。只要动下手,实践会告诉你一切。
第4个回答  2008-08-25
a[0][1]

*(*(p+1)+1)代表了a[1][1]
第一个*( + )是行指针
第二个*( + )是列指针
相似回答