为什么这是按价值传递?

Why is this passing by value?

我试图理解按值传递和按引用传递之间的区别,我以为我终于明白了,直到我看到这段代码:

void change(char *p1)

{
    p1="new";
}

int main()

{
    char *txt1=(char*)malloc(200*sizeof(char));
    
    txt1="original";
    printf("before :%s\n",txt1);
    change(txt1);
    printf("after :%s\n",txt1);
    
}

不是传递地址吗?然后更改它并使其指向其他地方?

输出为:

before : original

after : original

这是为什么?

这是将地址作为值传递。要让被调用方修改调用方的局部变量,请传递 应修改的地址

#include <stdio.h>

void change(char **p1)

{
    *p1="new";
}

int main(void)

{
    char *txt1; /* no causing memory leak */

    txt1="original";
    printf("before :%s\n",txt1);
    change(&txt1);
    printf("after :%s\n",txt1);

}

C 中没有按引用传递。函数参数使用按值传递。即 p1 本身是按值传递的。您可以从被调用的函数中更改 p1 (*p1) 指向的内存地址的内容,而不是 p1 本身。

澄清一下,为了改变变量var的内容,你需要传递var的地址,所以,如果你想改变一个指针本身,你需要传递函数指针的地址。

也就是说,please see this discussion on why not to cast the return value of malloc() and family in C

在函数调用change(txt1);中,txt1是按值传递的。它被复制到函数 change 的参数 p。这使得 pi 指向与 txt1 指向相同的字符串。当新字符串分配给 p1 时,p1 更改为指向该字符串,而 txt1 指向前一个字符串。

这个案例与

非常相似
char *s1 = "String";
char *s2 = s1;        // Both s1 and s2 points to same string  
s2 = "Another string" // Now s2 points to "Another string" while s1 pointing to "String". 

此外,您的代码导致内存泄漏。应该是

char *txt1=(char*)malloc(200*sizeof(char));
strcpy(txt1,"original");

按引用传递和按值传递。

这是我以前用过的一个例子。假设有以下两个函数:

void foo( T *p ) // where T is an arbitrary data type
{
  *p = new_value(); // write new value to the thing p points to
}

void bar( void )
{
  T var;
  foo( &var );  // write new value to var
}

为了函数 foo 更新 var 的内容(类型 T 的对象),我们必须传递一个指向 var 的指针(类型 T *).

如果我们把T换成指针类型P *,那么上面的代码就变成了

void foo( P **p )
{
  *p = new_value(); // write new value to the thing p points to
}

void bar( void )
{
  P *var;
  foo( &var );  // write new value to var
}

语义完全一样;我们希望 foovar 写入一个新值,因此我们将指针传递给 var。只是在这种情况下, var 已经是指针类型,所以我们最终将指针传递给指针。

基本上,foo要更新var的内容,必须传递表达式 &var作为参数,意思是形式参数 p 的类型总是比 var.

的类型多一级间接寻址
Type of var      Type of &var      Type of p
-----------      ------------      ---------
          T               T *            T *
        T *              T **           T **
       T **             T ***          T ***

等等