改变指针指向的地址为什么需要二维指针,从汇编角度分析
2011-06-01 01:32
399 查看
教科书上面有个比较经典的交换数字的问题。
如果以下面的 A表达式
int swap(int a, intb);
那么结果是a/b不能互换
如果想要达到a/b互换的小姑,只能以B的形式
int swap(int *a, int *b);
老师就老是告诉我们,因为这个时候需要传入指针,才会有效。一直以来都是在懵懂之间,知其然而不知其所以然。
今天忽然想到,于是打算从汇编的角度分析这个问题。
选的例子有点不同,看下面的代码:
这段程序运行后打印的结果是 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对应的值。
如果以下面的 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对应的值。
相关文章推荐
- C/C++ 指向字符的指针为什么可以用字符串来初始化,而不是字符地址。
- 从汇编的角度理解为什么c样式函数使用时,实参尽量使用指针传递
- 有时候需要改变指针参数地址
- 指向指针的指针**p改变*p值可以传递数值并且不改变p地址
- C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址
- 从汇编的角度分析函数指针
- 从gdb角度分析,为什么C语言中的scanf函数的变量要用“&”表示首地址
- 汇编分析参数传递中的地址传递与值传递的区别(指针,引用,值传递)
- 向null地址copy数据和不断改变指针指向
- 不能通过改变形参指针的值(形参所指向的地址)来改变实参指针的地址,实现改变实参指针所指向地址变量的值。
- 为什么未初始化的指针会指向一个不确定地址
- 从编译器角度分析C语言中数组名和指针的区别
- 为什么基类指针可以指向派生类对象,而派生类则不可以指向基类
- 基类指针为什么可以指向派生类,而派生类指针不可以指向基类
- 改变函数内部的this指针的指向
- 指针是用来指向地址的
- 为什么不能修改指向字符串的指针
- 试验指向常量二维字符串的常量指针
- 多角度分析为什么 Linux 的硬连接不能指向目录<转>
- C++输出字符型指针指向内存空间的地址