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

我有以下基本程序:

#include  void doit(char *c) { c = "world"; } int main() { char *c = "hello"; doit(c); printf("%s\n", c); return 0; } 

逐行:

  • c将地址存储到它指向的字符串(char序列)
  • * c在主要function中指向“你好”

现在当c(指针)传递给试图修改它的函数。 main中没有修改后的值。 为什么?

 #include  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函数中有一个指向字符串文字"hello"的指针c

 + -------- + + --------- +
 | 主要:c |  ----> |  “你好”|
 + -------- + + --------- +

然后当你将它传递给函数时,指针被复制,所以你有这个:

 + -------- +
 | 主要:c |  - 
 + -------- + \ + --------- +
               >  - > |  “你好”|
 + -------- + / + --------- +
 |  doit:c |  - 
 + -------- +

doit更改指针后,你有这样的:

 + -------- + + --------- +
 | 主要:c |  ----> |  “你好”|
 + -------- + + --------- +

 + -------- + + --------- +
 |  doit:c |  ----> |  “世界”|
 + -------- + + --------- +

对于第二个程序,它开始相同:

 + -------- + + --------- +
 | 主要:c |  ----> |  “你好”|
 + -------- + + --------- +

但是当你使用指向指针的指针调用时它会改变:

 + -------- + + -------- + + --------- +
 |  doit:c |  ----> | 主要:c |  ----> |  “你好”|
 + -------- + + -------- + + --------- +

然后在doit取消引用c会为您提供main原始 c指针,并对其进行更改

 + -------- + + -------- + + --------- +
 |  doit:c |  ----> | 主要:c |  ----> |  “世界”|
 + -------- + + -------- + + --------- +

在第一种情况下: –

 void doit(char *c) 

你是按值传递指针。 而且我们知道按值传递一些东西意味着函数不能改变传递的原始值。

在第一种情况下,您将指针 c的副本传递给doit 。 因此,无论您对指针进行哪些修改,它们都不会反映在调用者中。 您更改c 副本指向的位置,但原始c保持不变。

作为第二个示例中的对比,您将指针传递给指针,当您更改它指向的值时,您将更改原始指针c