您的位置:首页 > 其它

改变指针指向的地址为什么需要二维指针,从汇编角度分析

2011-06-01 01:32 399 查看
教科书上面有个比较经典的交换数字的问题。

如果以下面的 A表达式

int swap(int a, intb);

那么结果是a/b不能互换

如果想要达到a/b互换的小姑,只能以B的形式

int swap(int *a, int *b);

老师就老是告诉我们,因为这个时候需要传入指针,才会有效。一直以来都是在懵懂之间,知其然而不知其所以然。

今天忽然想到,于是打算从汇编的角度分析这个问题。

选的例子有点不同,看下面的代码:
int test (char **a, char *b)
{
char **pc;
pc = a;
*a = b;
b = *a;
return 0;
}
int main()
{
char a[2]={'a'};
char b[2]={'b'};
char *pa=&a;
char *pb=&b;
test(&pa,pb);
printf("%s,%s",pa,pb);
return 0;
}
~


这段程序运行后打印的结果是 b,b

这个说明了pa交换成功了而对pb的赋值实质上是没有影响到调用test函数的实参的。

这个中间是为什么呢?

在调用test后,我们可以通过gdb跟踪一些相关的变量来看看这之间的不同

进入test函数后

打印a/b变量的值和地址:

(gdb) display a
34: a = (char **) 0xbfffef90
(gdb) display b
35: b = 0xbfffef94 "b"
(gdb) display &a
36: &a = (char ***) 0xbfffef70
(gdb) display &b
37: &b = (char **) 0xbfffef74
(gdb) display *a
38: *a = 0xbfffef96 "a"

可以看到这个时候a的地址是0xbfffef90,b的地址是0xbfffef94

这时可能还不能看到问题,那么我们跳到上一层,再看看对应的pa已经pb的值

(gdb) display pa
39: pa = 0xbfffef96 "a"
(gdb) display pb
40: pb = 0xbfffef94 "b"
(gdb) display &pa
41: &pa = (char **) 0xbfffef90
(gdb) display &pb
42: &pb = (char **) 0xbfffef8c

这个时候可以看到有一处不同,那就是pa的地址&pa和test里面的a的值是相同的,都是0xbfffef90。

但是呢pb的地址&pb和test里面&b并不相同。

这个就导致了在test函数里面修改*pa那么就是修改内存0xbfffef90里面所存储的值,但是修改b呢,只是修改0xbfffef74对应的值,

并没有修改main函数里面&pb 0xbfffef8c对应的值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: