【发布时间】:2022-01-07 19:08:34
【问题描述】:
在 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 方法中修改是个好习惯吗?
如果指针引用的值是通过引用隐式传递的,为什么我会使用通过引用传递指针。
也许我遗漏了一些东西可以更好地解释一下吗?
【问题讨论】:
-
假设你有一个函数接收一个指针并且可以修改这个指针。通过引用将指针传递给函数不是完全合理吗?
-
C中没有“引用传递”,只有值传递。
-
@WilliamPursell:在 C++ 采用术语“引用”来表示语言的内置特性之前,它在 C 的上下文中用于表示手动传递指针。事实上,它仍然以这种方式使用,并且 C 标准说指针提供对对象的引用。当有人说,在 C 的上下文中,某些东西是通过引用传递的,他们的意思是源代码传递了那个东西的地址。过去和现在在 C 语境中对英语的使用在 C++ 开发采用该术语作为其自身用于不同目的时并没有改变。
-
@Eric:你说的一切都是真的,但 OP 似乎确实混合了 C 和 C++ 的术语。我认为他的预期问题的答案是,仅当要修改指针本身时,才需要通过地址/引用传递指针。如果只想修改指针的目标,按值传递指针就可以了。
-
@chux-ReinstateMonica 我不得不参考上面 Eric 的原始评论。我正在尝试将指针而不是指针的副本手动传递给“子例程”堆栈帧。本质上,当我说在 c 的上下文中通过引用传递时,我是在传递一个指向指针的指针。
标签: c pointers pass-by-reference pass-by-value