单重指针已经够蛋疼了,C语言中还引入了双重指针,甚至若干重指针。使得这个情况变得更加复杂。虽然以前一直觉得双重指针也不过如此,指针的指针嘛,还不是照样理解,但是上一次重删代码中,因为管理海量数据,引入了大量的指针操作,并且为了函数封装,采用了指针作为参数来传递。因此出现了较多问题,现在感觉很有必要写一篇有关双重指针的博文。
先看一个例子:
程序1
void change(char* p)
{
p = "bbb";
}
int main(int argc, char* argv[])
{
char *v = "aaa";
change(v);
printf("%s",v);
return 0;
}
我们发现输出的结果仍然是aaa。
对它进行修改:
程序2
void change(char** p)
{
*p = "bbb";
}
int main(int argc, char* argv[])
{
char *v = "aaa";
change(&v);
printf("%s",v);
return 0;
}
此时输出的结果为bbb.
分析:
出现以上现象的原因是因为这个函数调用的时候,这个指针作为参数传递问题。程序1中,实际上,当我们调用函数change,把指针char*v,当做参数传入的时候,这里还隐藏了一个赋值的操作,也就是说,传入到change函数中的是另外某个参数char* x,x=v;所以说最后改变的只不过是x,v指向的东西并没有改变,所以输出来,还是aaa。如下图所示:
在程序2,操作过程中,指针v本身的地址值始终没有改变,改变的是指针v所指向的地址变化了。它不再指向”aaa”所在的地址,而是”bbb”所在的地址。
总结:当指针作为函数参数传递的时候,如果想改变指针所指向的地址,比如想把char*v,从指向“aaa”转到指向“bbb”,那么需要采用双重指针传递的方式。或者说想通过调用函数的方式,给指针用malloc 分配新的地址的时候,也需要采用双重指针,才能实现真正的分配,否则是分配不成功的。
而如果只是想改变,指针所指向的地址里面的内容的时候,则采用单重指针就可以了,比如想把“aaa”改成“aab”,那么直接用单重指针传递就ok了,因为指针指向的地址不需要改变。代码就应该写成,如下:
程序3
void change(char* p)
{
*(p+2) = 'b';
}
int main(int argc, char* argv[])
{
char *v = "aaa";
change(v);
printf("%s",v);
return 0;
}
如下图: