为什么这是按价值传递?
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
}
语义完全一样;我们希望 foo
向 var
写入一个新值,因此我们将指针传递给 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 ***
等等
我试图理解按值传递和按引用传递之间的区别,我以为我终于明白了,直到我看到这段代码:
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
}
语义完全一样;我们希望 foo
向 var
写入一个新值,因此我们将指针传递给 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 ***
等等