在 C 中通过引用传递指针和通过值传递指针有什么区别?
我的理解是,当您将参数传递给方法时,会创建一个新的堆栈帧,并且这些值将被复制到不同的内存地址,除非通过引用传递。如果通过引用传递,则传递内存地址。
在使用指针时,我注意到,如果我按值传递 char* 并在返回主堆栈帧时在不同的堆栈帧中修改它,则 ptr 的值已被修改。
我编写了简短的代码来展示我在说什么。
//test pointer ref
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void passbyval(char const *lit,char* str){
printf("---passbyval---\n");
printf("%s\t%p\n",lit,&lit);
//modify string
strncat(&str[2],"/",1);
printf("%s\t%p\n",str, &str);
}
void passbyref(char const **lit, char** str){
printf("---passbyref---\n");
printf("%s\t%p\n",*lit,&*lit);
//modify string
strncat(&(*str)[1],"/",1);
printf("%s\t%p\n",*str,&*str);
}
int main(){
char const *litstr = "hello this is a test";
char *str = (char*)malloc(sizeof(char)*100);
scanf("%[^\n]",str);
printf("---main---\n");
//print original value and address
printf("%s\t%p\n",litstr,&litstr);
printf("%s\t%p\n",str,&str);
passbyval(litstr,str);
//modified value and address from pass by value
printf("\nretfromval:%s\t%p\n",str,&str);
passbyref(&litstr,&str);
//modified value and address from pass by ref
printf("\nretfromref:%s\t%p\n",str,&str);
free(str);
return EXIT_SUCCESS;
}
不通过引用传递是个好习惯吗char*
你想在 void 方法中修改吗?
让我摸不着头脑,如果指针引用的值是通过引用隐式传递的,为什么我会对指针使用按引用传递。
也许我错过了一些东西,可以更好地解释一下吗?
最佳答案
When working with pointers I noticed that if I pass a char* by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.
你的例子都没有这样做。此外,您的代码都不会打印 litstr
或 str
的值。要打印指针的值,请删除所有 printf
调用中的 &
。然后您将看到调用例程和被调用例程中的指针值是相同的。
在main
中,printf("%s\t%p\n",litstr,&litstr);
打印:
- 在内存中从
litstr
值的地址开始的字符串(因为%s
和litstr
)和< litstr
的地址(不是值)(因为%p
和&litstr
)。
同样,printf("%s\t%p\n",str,&str);
打印 str
处的字符串以及 str 的地址
.
在 passbyval
中,printf("%s\t%p\n",lit,&lit);
打印 lit
处的字符串以及 lit
的地址。由于lit
是passbyval
的参数,它有自己的地址,与litstr
的地址不同。如果您打印了 litstr
和 lit
的值,而不是它们的地址,您会看到它们是相同的。
同样,printf("%s\t%p\n",str, &str);
打印 str
处的字符串以及 str 的地址
。 passbyval
中参数str
的地址与main
中本地对象str
的地址不同,但是它们的值是相同的。
在 passbyref
中,printf("%s\t%p\n",*lit,&*lit);
打印 lit< 处的字符串
和 *lit
的地址。由于 lit
是 main
中 litstr
的地址,因此 *lit
就是 litstr
>,所以&*lit
就是litstr
的地址。 litstr
的值为 *lit
。
类似地,printf("%s\t%p\n",*str,&*str);
打印 *str
处的字符串和地址*str
,即main
中str
的地址。
关于c - 按值传递指针或按引用传递指针是否相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70626030/