作者想通过如下代码来为变量a申请内存,并将其指向的值改为5.
#include <stdio.h>
void foo(int * value)
{
value=(int *)malloc(4);
*value = 5;
}
int main()
{
int *a=NULL;
foo(a);
printf("%d\n",a);
}
但是程序跑出来的 结果是0,也就是说a这个指针变量中存储的地址是NULL,根本就没发生改变!
倒腾了半天,在百度知道上也发了问题。最终经过大牛指点代码修改为一下就可以了:
#include <stdio.h>
void foo(int ** value)
{
<span style="white-space:pre"> </span>*value=(int *)malloc(4);
<span style="white-space:pre"> </span>**value = 5;
}
int main()
{
int *a=NULL;
foo(&a);
printf("%d\n",*a);
}
运行结果是5.
(不知道各位有没有注意到第一段代码printf(...,a)第二段是printf(...,*a)。第一段如果写*a的话就是内存报错,因为a是空地址取不到值。)
弄完之后又查阅了一些资料,现在把地址传递与值传递辨析一下:
首先,C语言所有的传递都是值传递。
我们所谓地址传递只不过是指针变量之间的值传递。看下面的代码:
void swap(int *a,int *b) //地址传递
{
int temp;
temp = *a;
*a = *b;
*b =temp;
}
参数传递过来以后,函数新建一个变量a复制第一个实参的内容(变量内容是地址),b复制第二个实参的内容(变量内容是地址)。
a变量与实参1都是指向同一个变量。所以*a发生改变当然是双向的。b同理。
但是我们如果想修改实参1的内容(指针变量中存储的地址)也就是文章一开始想给a申请动态内存就不能按照第一段代码来了。
需要按照第二段代码
#include <stdio.h>
void foo(int ** value)
{
<span> </span>*value=(int *)malloc(4);
<span> </span>**value = 5;
}
int main()
{
int *a=NULL;
foo(&a);
printf("%d\n",*a);
}
传递指向a这个指针变量的地址给 value(**表示二级指针,指向指针变量的指针变量),注意因为是C都是值传递,所以
1. value变量复制了a这个指针变量的地址(不是a的内容);
2. *value表示a的内容(即a中存储的地址);
3. **value表示a存储的地址所指向的内容。
理清楚以上三点基本上就能很好理解这篇文章说的东西了。
这样就达到了修改a的内容,以及a所指向的内容两个目标了。