我有以下基本程序:
#include <stdio.h> void doit(char *c) { c = "world"; } int main() { char *c = "hello"; doit(c); printf("%s\n",c); return 0; }
逐行:
> c将地址存储到它指向的字符串(char序列)
> * c指向主函数中的“hello”
现在当c(指针)传递给试图修改它的函数. main中没有修改后的值.为什么?
#include <stdio.h> void doit(char **c) { *c = "world"; } int main() { char *c = "hello"; doit(&c); printf("%s\n",c); return 0; }
工作得很好?我期待第一个例子自己工作正常,因为我传递了doit(c),它已经是我想要修改的字符串的指针.
解决方法
这是因为在第一个版本中,您按值传递指针.这意味着复制了来自main的实际指针,而在doit函数中,您只需修改副本.
在第二个版本中,您通过将指针传递给指针来模拟通过引用传递(C没有正确的引用).
让我们看看这是否让你更清楚.
对于第一个程序,在main函数中有一个指针c指向字符串文字“hello”:
+--------+ +---------+ | main:c | ----> | "hello" | +--------+ +---------+
然后当你将它传递给函数时,指针被复制,所以你有这个:
+--------+ | main:c | -- +--------+ \ +---------+ >--> | "hello" | +--------+ / +---------+ | doit:c | -- +--------+
在doit中更改指针后,您有以下内容:
+--------+ +---------+ | main:c | ----> | "hello" | +--------+ +---------+ +--------+ +---------+ | doit:c | ----> | "world" | +--------+ +---------+
对于第二个程序,它开始相同:
+--------+ +---------+ | main:c | ----> | "hello" | +--------+ +---------+
但是当你使用指向指针的指针调用时它会改变:
+--------+ +--------+ +---------+ | doit:c | ----> | main:c | ----> | "hello" | +--------+ +--------+ +---------+
然后在doit中取消引用c会为您提供main中的原始c指针,并对其进行更改
+--------+ +--------+ +---------+ | doit:c | ----> | main:c | ----> | "world" | +--------+ +--------+ +---------+