基本C指针并通过引用传递混淆

时间:2014-12-15 11:48:46

标签: c

我有以下基本程序:

#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在主要功能
  • 中指向“你好”

现在当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),它已经是我想要修改的字符串的指针。

3 个答案:

答案 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