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

    技术2022-05-20  64

    教科书上面有个比较经典的交换数字的问题。

    如果以下面的 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对应的值。


    最新回复(0)