C里面的指针怪问题,很困惑
程序如下:
main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p;
p=a;
p=p+1;
}
调试时候,
a的地址:0x240ff30
p=a 所以p的地址:0x240ff30
但是最后p=p+1后 p的地址:0x240ff34
问题:
p开始的时候已经指向a,即数组的行地址,所以理论执行p+1后,地址应该为0x240ff40。但是调试结果并不相同。
另外,我试过将最后两句改成:
p=a+1; 0x240ff40
p=p+1; 0x240ff44
结果显示p+1指向下一列元素,为何?
问题点数:0、回复次数:28Top
1 楼milozy1983(Detective)回复于 2004-12-02 18:38:01 得分 0
我把p=p+1理解为基址寻址法偏一地址改变,而p=a+1是基址改变Top
2 楼BlackEagle_(黑鹰)回复于 2004-12-02 18:51:10 得分 0
p = a[0] 才是指向数组的首行地址Top
3 楼pikaqiu96(学无止境)回复于 2004-12-02 18:59:59 得分 0
p=p+1后,p地址应该为0x240ff38,你怎么认为是0x240ff40?
每一行不是8个字节吗?Top
4 楼great_chenliang(Eric)回复于 2004-12-02 19:00:27 得分 0
p=a 所以p的值(注意,不是地址):0x240ff30
但是最后p=p+1后 p的值:0x240ff34
不对吗?32位int为4字节呀。Top
5 楼cyberkit(木子)回复于 2004-12-02 19:04:40 得分 0
注意 int *p 这个语句
指针p是int型的!当你对它进行p=p+1时,是与类型相关的,但跟前面的数组大小无关。
int的大小是4,所以p=p+1比原来大了一个int,就这么简单啦。
问题1和问题2本质是一样的,关键是你没理解指针的加减跟自己的类型是相关的!Top
6 楼raining(下雨了)回复于 2004-12-02 19:06:48 得分 0
没有分?Top
7 楼yangsiqun(灌水是我有声的抗议)回复于 2004-12-03 18:23:18 得分 0
cyberkit木子: 正解Top
8 楼jnch(*ω*小笨)回复于 2004-12-03 19:07:13 得分 0
UPTop
9 楼bingbing1981(^_^)回复于 2004-12-03 19:39:39 得分 0
木子说的好Top
10 楼clwforluv(上海紧缺人才)回复于 2004-12-03 20:54:02 得分 0
a的地址:0x240ff30
p=a 所以p的地址:0x240ff30
大部分的问题大家都说完了,我也不多说了,不过有个地方还是希望楼主注意一下,从以上楼主说的这两句话我相信楼主有一点还有误区,int *p;p=a;这里,p指向了a的地址,但是p本身的地址并不是a的地址,楼主可以用这个语句验证:
int *p,x=5
p=&x;
printf("%p,%p",p,&p);
我们说将某个地址赋个某个指针变量时候,被赋值的指针变量他本身是有自己的地址的,不会随着被赋值的变化而变化的,只是他所指向的地址是变化了。Top
11 楼bsnhk((void *)0)回复于 2004-12-03 21:06:44 得分 0
木子说的不全对,p的类型是int*而不是int.
在c语言中,任何维数组本质上都是一维数组,所以考察任何维数组的指针问题时,绝对必须从一维数组的角度去考察。数组名a除去应用于sizeof和&这两个运算符的场合外,其意义都是指数组a中下标为0的那个元素的指针,这时的下标为0的数组元素就是a[0],所以数组名a也就是&a[0],a+1就是(&a[0])+1,也就是&a[1]。
对于任何维的数组a,&a的意义是“指向一维数组a的指针”(而不是指向一维数组a中元素的指针)。
小结:a、&a[0]是同类型的指针,都是“指向一维数组a中下标为0的那个元素的指针”;&a是指向一维数组a的指针;&a[0][0]是指向一维数组a[0]( 注意,a[0]就是一维数组a[0][4]的名称,下标[4]是指这个一维数组有4个元素)中下标为0的元素的指针。再次提醒注意“指向数组的指针”和“指向数组元素的指针”是有区别的,在多维数组中,各个层次上的“指向数组的指针”和“指向数组元素的指针”也都是不同的(指针类型不同)。
呵呵,这些问题要上机实践才能体会到!Top
12 楼ej(辉)回复于 2004-12-03 21:29:19 得分 0
解答多样性啊,等我了解一下Top
13 楼bbn9435(bbn)回复于 2004-12-03 21:37:44 得分 0
指针的算术运算只有加和减.
指针每加一次,它就指向他的基本类型的下一个元素的内存位置;
指针每减一次,它就指向前面一个元素的内存位置.
就是说:所有的指针的算术运算都是根据指针的具体类型来计算的:-)Top
14 楼ej(辉)回复于 2004-12-03 23:01:59 得分 0
我理解是这样的:
a[3][4]是一个二维数组。“a”与“a[0]“都是数组的首地址,但“a”是指向行的,“a[0]”是指向列的。
所以若数组首地址为:0x240ff30
则a由于指向行,所以a+1应该就指向下一行,地址应该是:0x240ff40(一行有4个数据,一个4字节)
a[0]由于指向列,则a[0]+1的地址应该指向下一列,地址应该是:0x240ff34
大家觉得有没错?Top
15 楼great_chenliang(Eric)回复于 2004-12-03 23:18:23 得分 0
人家白讲了。Top
16 楼great_chenliang(Eric)回复于 2004-12-03 23:21:06 得分 0
[]这个东西在标准里不叫类型标识符,而叫存储标识符。所以,你可以推得,C/C++没有数组类型。这下懂了吧。Top
17 楼luyg614(CouCou)回复于 2004-12-03 23:29:03 得分 0
int (* p)[4];
p是指向指针的指针
p=a p是a的地址
*(p+i) 应该是第i行的地址..Top
18 楼bbn9435(bbn)回复于 2004-12-03 23:40:36 得分 0
我是这么认为的:
一个"数",可以认为它表示一个"数值",也可以表示一个"地址"
对于n维数组a[1维][2维]...[n维]来说
可以看作是多个1维数组嵌套组成的
只不过1维数组包含的是"数值"
而n维数组包含的是"地址",由这些"地址"指向另一个(n-1)维数组,一直到1维数组罢了
所以
对于n维数组a[1维][2维]...[n维](n>=1)来说
a表示的是数组a第1个元素的"数",即a[0].至于这个数表示的意思是"数值"还是"地址",就看这个数组的维数了
a+2表示的是数组a第3个元素的"数",即a[2].同理,这个数表示的意思是"数值"还是"地址",也看这个数组的维数了
如果a[0]这个"数"表示的是"地址",那么就分析a[0]这个数组喽.
Top
19 楼bsnhk((void *)0)回复于 2004-12-04 00:02:36 得分 0
有些东西听别人解释是没多大用处的,要自己冥思苦想后才能得道!Top
20 楼bbjt()回复于 2004-12-04 00:11:48 得分 0
开始觉得木子说的不错,后来想想bsnhk(欲哥)说的也有理。Top
21 楼pig_liang(朱)回复于 2004-12-04 02:11:02 得分 0
bsnhk(欲哥)对p=a+1; 0x240ff40作出了很好的解释.
而对于另外一个问题则是:在C/C++语言中指针的大小就是4字节,所以当p+1时,地址加4,所以p=p+1; 0x240ff44Top
22 楼bbn9435(bbn)回复于 2004-12-04 08:47:51 得分 0
TO: pig_liang(朱)
好像错了吧??
c中的指针运算应该是跟本身指向的数据类型有关的
比方说:
int *pn 和 char * pch都加1
如果起始地址都为1000的话
那么pn+1=1004,而pch+1=1001
就是说pn是int *类型的,而pch是char *类型的
Top
23 楼sink()回复于 2004-12-04 10:37:52 得分 0
p和a的移动粒度是不同的,a+1,a指向a[1]的首地址,可以把这个二维数组看成3行4列的,a+1指向第二行的首地址,在你的系统中每个int占4个字节,所以p=a+1=+4*4=a+16=a+0x10=0x240ff40
p=a时,p++,p指向第一个元素的地址,你的系统中int4位,所以p+1=0x240ff34Top
24 楼ej(辉)回复于 2004-12-04 11:54:46 得分 0
我已经瞑想了两天了。。。。。
看了大家说的,就是说
p=a 0x240ff30
p=p+1 0x240ff34 这时的p+1的值是按照p原来的类型累加的,因为原来是是int型,所以0x240ff34
如果要另p=p+1移动到下一行,就只有定义改为int (*p)[4]。
大家觉得如何?
Top
25 楼williamVII(spread)回复于 2004-12-04 16:27:22 得分 0
so simpleTop
26 楼tcdddd(迷茫男人)回复于 2004-12-04 19:02:57 得分 0
bsnhk(欲哥)+ ej(辉)的解释 ,这样应该足够解释这道题了Top
27 楼bsnhk((void *)0)回复于 2004-12-05 10:19:43 得分 0
to ej(辉):
"如果要另p=p+1移动到下一行,就只有定义改为int (*p)[4]。"
错,应该将定义改为int (*p)[3][4];Top
28 楼wolfkain()回复于 2004-12-05 13:52:48 得分 0
int a[n][m],*p;
时a的指针类型和p不同,一个指向2*m个字节的类型,一个是指向2*1个字节的类型。
同理:
int a[i][j][k],*p;
时a的指针类型和p不同,一个指向2*j*k个字节的类型,一个是指向2*1个字节的类型。
也就是说对于N维数组a[][][]...[],数组名a相当于一个指向N-1维数组的指针。Top




