C语言求二维数组之和

#include"stdio.h"
main()
{
int i,s=0,*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

for(p=a[0];p<a[0]+12;p++)
s+=*p;
printf("s=%d\n",s);
}
//a[]与a为什么不相等啊 我将for(p=a[0];p<a[0]+12;p++)改为for(p=a;p<a+12;p++)就出错呢。对于指针还不是很熟练

for(p=a;p<a+12;p++)
1, p = a; 是ok的。
2, p < a + 12; 就不ok了: a是一个二维数组,他的长度是12 * sizeof(int), 在32位机上是48, 这里的a+12 就是 a 地址后面的 12 * 48 的位置, a[0] + 12 是a地址后12 * 4的位置!追问

不好意思,我是一点没看懂,,,p=a我知道当a为一维数组的时候是对的,当a为二维的时候还不是很懂

追答

char b, *a = &b; 如果b的地址是0x234,那么a的值就是0x234. a + 1就是 0x235.
int b, *a = &b; 如果b的地址是0x234,那么a的值就是0x234. a + 4就是 0x238.

就是说指针类型不同,其加减运算的结果不同!

追问

........越来越迷糊

追答

!!!
想一下,既然所有的指针保存的是内存地址,那还分 int* char*干什么?
就是因为不同类型的指针其加减运算不同。
char*型加1 就是其地址加1
int*型加1,因为int是4个字节, 其地址其实是加了4

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-11-03
p=a[0],是把&a[0][0]赋给p,也就是p是指向列的,因此p++操作,是将指针移动一列,也就是从a[i][j]移动到a[i][j+1]
如果你把a赋给了p,(先不说正确与否,实际上是错的,但是假定正确)那么实际上是把&a[0]赋给了p,那么p++操作,是将指针移动一行,也就是从a[i][j]移动到a[i+1][j],。
我们再来看看 为什么说p=a本身有错,因为定义中 int *p,a[3][4]; p是指向一个数据的指针,而a实际上是指向a[0] 、a[1]、a[2]的,但是a[0] a[1] a[2]他们都是一个一位数组,都包含多个数据,因此要想把a赋给p,p应该这样定义 int (*p)[4] ,也就是p也指向一个含有四个元素的地址,这样a+1相当于移动一行,也就是从a[i][j]一定到a[i+1][j],p+1也是一定移动了个元素(就是一行元素的个数)。
因此,指针赋值的时候要注意,指针指向的元素个数究竟匹配不匹配,并不是所有指针都可以互相赋值的。

修改如下:
main()
{
int i,s=0,(*p)[4],a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

for(p=a;p<a+3;p++)
for(i=0;i<4;i++)
s+=*(*p+i);
printf("s=%d\n",s);
}
第2个回答  2011-11-03
简单的说:a[0]是一个数组中得一个元素,而a是一个变量,两个本质就不一样了。
再详细一点:p=a[0]是指指针p指向数组a[]的第一个元素a[0],而a[0]相当于第1个元素的地址。p=a,这个本身就有错了撒a是一个变量名,p是指针,将变量值赋给指针??所以就错了撒,应该是把变量地址赋给指针p,所以应该是p=&a;但是你之前没有定义变量a,所以编译的时候还是会报错,说没定义变量a.
第3个回答  2011-11-03
这就是关于普通量存到内存后,用指针引用的话,指针的不正确表示带来的,也就是
指针其实和普通量(尤其是二维数组)取元素的位置不一致导致的。相当于他两个的偏移量是不一致的。
第4个回答  2011-11-03
打印了下 a的地址是 XXXXX1C0
a[0]+1的地址是 XXXXX1C4
a+1 的地址是 XXXXX 1d0

因为在二维数组中, a 相当于 &a[0], a[0] 相当于 &a[0][0];
所以 p=a+1 指针p移动4个数(16个字节) a[0]+1 指针p移动1个数(4字节).
综上,p<a+12,指针P已经超出了数组范围。所以S出错。追问

那应该就是a[0]和a的问题一维数组p=a正确,二维数组p=a[0]正确兄台切中了要点