按值或按引用传递指针相同
Is passing pointer by value or by reference the same
在 C 中按引用传递指针和按值传递指针有什么区别?
我的理解是,当您将参数传递给方法时,会创建一个新的堆栈框架,并且除非通过引用传递,否则这些值将被复制到不同的内存地址。如果通过引用传递内存地址。
在使用指针时,我注意到如果我按值传递 char* 并在我 return 返回主堆栈帧时在不同的堆栈帧中修改它,则 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.
None 您的示例执行此操作。此外,您的代码的 none 会打印 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
是[=10=的地址]. litstr
的值将是 *lit
.
类似地,printf("%s\t%p\n",*str,&*str);
打印*str
处的字符串和*str
的地址,即main
中str
的地址。
您需要了解指针和数组的工作原理。
pointer
是一个独立的对象,有自己的引用,持有底层对象的引用。
char *p = "aaa";
print("%p\n", (void *)p); //prints the reference of the string literal "aaa"
print("%p\n", (void *)&p); //prints the reference of the pointer `p`
数组是连续的内存块。数组衰减 为指针。这些指针在内存中没有物理表示,只是对数组第一个元素的引用。
char p[] = "aaa";
print("%p\n", (void *)p); //reference of the first element
//of the array p the type is `char *`
//(pointer to char)
print("%p\n", (void *)&p); //reference of the first element of the
//array p the type is `char (*)[4]`
//(pointer to an array of 4 char elements)
What is the difference between passing a pointer by reference and passing a pointer by value in C?
在C语言中没有通过引用传递指针,所有变量都是按值传递,甚至是指针。
My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.
同样,指针不是通过引用传递的,传递的是指针中存储的值的副本,即它指向的地址,你可以通过更改函数内部指针的值,并检查它如何反映在原始指针上,扰流板,它没有。
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.*
你传递的是一个地址,一个存储一些数据的内存位置,当你更改存储在该内存地址中的数据时,无论你在哪里做,它都是永久性的,事实上这是其中之一使用指针的优点,您可以在声明范围之外更改某些变量的内容。
What is the difference between passing a pointer by reference and passing a pointer by value in C.
在 C 中,有多种方法可以在将参数传递给函数之前对其进行预处理。
不处理
将参数的副本提供给函数。 char *s = ...; puts(s);
。 puts()
得到一份 s
.
普通参数提升
在将副本提供给函数之前,参数被提升为 int, unsigned, double, ...
。 float fl = 12.5f; printf("%g", fl);
printf()
得到一份 double 12.5
.
函数转换为地址
和tss_create(tss_t *key, tss_dtor_t dtor);
一样,tss_dtor_t
是函数指针类型void (*)(void*)
。 tss_create(... , foo)
不采用函数 foo()
并传递它。而是传递函数地址的副本。
数组转换为其第一个元素的地址
使用 char s[] = "Hello; puts(s);
,&s[0]
的副本被传递给 puts()
。
现在,这些是不是像 OP 的 ?
是的。
和char *end[1]; strtod("123.4", end);
,从调用者的角度来看,end
在里面调整了整个 strtod()
等从调用者的 POV 中表现和闻起来像“通过引用传递”。这在技术上仍然是“传递副本”,但副本是参数第一个元素的地址。
除此之外,我看不到“在 C 中通过引用传递指针和通过值传递指针”之间的差异。
在 C 中按引用传递指针和按值传递指针有什么区别?
我的理解是,当您将参数传递给方法时,会创建一个新的堆栈框架,并且除非通过引用传递,否则这些值将被复制到不同的内存地址。如果通过引用传递内存地址。
在使用指针时,我注意到如果我按值传递 char* 并在我 return 返回主堆栈帧时在不同的堆栈帧中修改它,则 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.
None 您的示例执行此操作。此外,您的代码的 none 会打印 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
是[=10=的地址]. litstr
的值将是 *lit
.
类似地,printf("%s\t%p\n",*str,&*str);
打印*str
处的字符串和*str
的地址,即main
中str
的地址。
您需要了解指针和数组的工作原理。
pointer
是一个独立的对象,有自己的引用,持有底层对象的引用。
char *p = "aaa";
print("%p\n", (void *)p); //prints the reference of the string literal "aaa"
print("%p\n", (void *)&p); //prints the reference of the pointer `p`
数组是连续的内存块。数组衰减 为指针。这些指针在内存中没有物理表示,只是对数组第一个元素的引用。
char p[] = "aaa";
print("%p\n", (void *)p); //reference of the first element
//of the array p the type is `char *`
//(pointer to char)
print("%p\n", (void *)&p); //reference of the first element of the
//array p the type is `char (*)[4]`
//(pointer to an array of 4 char elements)
What is the difference between passing a pointer by reference and passing a pointer by value in C?
在C语言中没有通过引用传递指针,所有变量都是按值传递,甚至是指针。
My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.
同样,指针不是通过引用传递的,传递的是指针中存储的值的副本,即它指向的地址,你可以通过更改函数内部指针的值,并检查它如何反映在原始指针上,扰流板,它没有。
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.*
你传递的是一个地址,一个存储一些数据的内存位置,当你更改存储在该内存地址中的数据时,无论你在哪里做,它都是永久性的,事实上这是其中之一使用指针的优点,您可以在声明范围之外更改某些变量的内容。
What is the difference between passing a pointer by reference and passing a pointer by value in C.
在 C 中,有多种方法可以在将参数传递给函数之前对其进行预处理。
不处理
将参数的副本提供给函数。char *s = ...; puts(s);
。puts()
得到一份s
.普通参数提升
在将副本提供给函数之前,参数被提升为int, unsigned, double, ...
。float fl = 12.5f; printf("%g", fl);
printf()
得到一份double 12.5
.函数转换为地址
和tss_create(tss_t *key, tss_dtor_t dtor);
一样,tss_dtor_t
是函数指针类型void (*)(void*)
。tss_create(... , foo)
不采用函数foo()
并传递它。而是传递函数地址的副本。数组转换为其第一个元素的地址
使用char s[] = "Hello; puts(s);
,&s[0]
的副本被传递给puts()
。
现在,这些是不是像 OP 的
是的。
和
char *end[1]; strtod("123.4", end);
,从调用者的角度来看,end
在里面调整了整个strtod()
等从调用者的 POV 中表现和闻起来像“通过引用传递”。这在技术上仍然是“传递副本”,但副本是参数第一个元素的地址。
除此之外,我看不到“在 C 中通过引用传递指针和通过值传递指针”之间的差异。