我有以下基本程序:
#include <stdio.h>
void doit(char *c) {
c = "world";
}
int main() {
char *c = "hello";
doit(c);
printf("%s\n", c);
return 0;
}
逐行:
现在当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)
,它已经是我想要修改的字符串的指针。
答案 0 :(得分:9)
这是因为在第一个版本中,您通过值传递指针。这意味着来自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" | +--------+ +--------+ +---------+
然后在c
中解除引用doit
,为您提供来自c
的原始 main
指针,并将其更改为
+--------+ +--------+ +---------+ | doit:c | ----> | main:c | ----> | "world" | +--------+ +--------+ +---------+
答案 1 :(得分:2)
在第一种情况下: -
void doit(char *c)
您正在按值传递指针。而且我们知道按值传递某些东西意味着函数不能改变传递的原始值。
答案 2 :(得分:1)
在第一种情况下,您将指针 c
的副本传递给doit
。因此,无论您对指针进行哪些修改,它们都不会反映在调用者中。您更改c
的副本指向的位置,但原始c
保持不变。
作为第二个示例中的对比,您将指针传递给指针,当您更改其指向的值时,您将更改原始指针c
。