以一段代码切入主题吧。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void function1(int *v)
{
v = (int *)malloc(sizeof(int));
*v = 100;
}
void main()
{
int *v = NULL;
function1(v);
printf("%d\n",*v);
}
你会发现这段代码不能运行,为什么呢?不是传递的指针吗?又不是值传递。一直以来,在C程序员的脑子里都知道值传递和指针传递这个概念(不要跟我说不知道,否则你就说我不是C程序员),但却没有真正理解函数参数传递的本质。
跟着我后面走,忘却什么值和指针,乱七八糟的东西,烦死了。你现在应该想明白,指针就是一个变量,存放的是地址,不过也是一个值罢了,只不过特殊一点。再明确一点,函数参数的传递实际上是一个拷贝的过程,而且离奇的是,都是拷贝。
现在回答我,主函数function1(v)是不是传递了一个值(这个值是一个地址)给被调函数?那么被调函数就把这个值(也就是地址)拷贝了下来。本来没有什么事的,狗血的是他执行了v = (int *)malloc(sizeof(int));这样一条语句,这条语句什么意思啊,哦,申请一块内存,并把这块内存的地址返回给v,呵呵,悄然把地址修改啦。这时主函数和被调函数中的指针指向的东西没有半毛关系了,主函数中v还是NULL,所以……
怎么修改呢?看下面的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void function2(int **v)
{
*v = (int *)malloc(sizeof(int));
**v = 10;
}
void main()
{
int *v;
function2(&v);
printf("%d\n",*v);
}
被调函数要求传递指针的地址,好,那就把主函数中某个指针的地址复制过来。注意哦*v = (int *)malloc(sizeof(int));这条语句分配一块内存,返回给谁呢?指针的指针的地址还是指针,当然是指针了,想明白。(在被调函数中**v代表指针指向的值,*v代表指针,v代表指针的地址),也许你还不明白,看个图。
我们惊奇地发现,我们只是把指针的地址复制了过来,但这个地址仍然指向这个指针,明白了吧。
其实我不在忙喜欢这种方式,我喜欢要么在被调函数外面先分配好内存,再把指针传递进去,要么干脆在被调函数里面定义指针,分配内存,然后返回指针就好了,这样不容易出错。