[英]Why must I pass a string by reference in order to change where it points?
I'm acquainting myself with c-strings and pointers by using a very simple program. 我通过使用一个非常简单的程序来熟悉C字符串和指针。
This version, which passes in a string by reference, works: 此版本通过引用传递字符串,其工作原理是:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void test(char **string) {
*string = (char *)malloc(5);
char *temp = "hell";
strcpy(*string, temp);
}
int main(int argc, char *argv[]) {
char *string = NULL;
test(&string);
printf("%s\n", string);
return 0;
}
It prints "hell". 它打印“地狱”。
This version, which simply passes the string by value, does not work, and results in a SEGFAULT: 该版本仅按值传递字符串,因此不起作用,并导致SEGFAULT:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void test(char *string) {
string = (char *)malloc(5);
char *temp = "hell";
strcpy(string, temp);
}
int main(int argc, char *argv[]) {
char *string = NULL;
test(string);
printf("%s\n", string);
return 0;
}
From what I know, the first version makes sense because I pass in the address of the address of the string. 据我所知,第一个版本很有意义,因为我传入了字符串地址的地址。 Thus, when I dereference this double pointer, I get the real address of the string and can reassign it with malloc.
因此,当我取消引用此双指针时,可以获得字符串的真实地址,并可以使用malloc重新分配它。
The second version, however, I'm kind of unclear why it doesn't work. 但是第二个版本,我不清楚为什么它不起作用。 In this version I pass the address of string into the test function.
在此版本中,我将字符串的地址传递给测试函数。 I read that everything in C is passed by value but that array names are actually addresses.
我读到C语言中的所有内容都是按值传递的,但是数组名称实际上是地址。 Doesn't this mean that I'm passing in the actual address of string into test?
这是否意味着我要将字符串的实际地址传递给test? Shouldn't things work out the same?
事情不应该一样吗? I'm confused, please help me out.
我很困惑,请帮帮我。
Remember This : In C programming to use a value,you pass "by value". 切记:在C编程中使用值时,您传递“按值”。 To change a value you must pass "by address".
要更改值,您必须传递“按地址”。 So,if what you want to change is an address,then you need to pass its address to change it.otherwise you may only use it.
因此,如果要更改的是地址,则需要传递其地址以进行更改。否则,只能使用它。
When you pass an argument "by value", the value of the argument is copied into the formal argument in the function. 当您通过“按值”传递参数时,参数的值将被复制到函数中的形式参数中。 Changing a copy (in your case
string
inside the test
function) will of course not change the original ( string
in the main
function). 当然,更改副本(在您的情况下为
test
函数中的string
)不会更改原始副本( main
函数中的string
)。
On a side-note, C doesn't actually have "pass by reference", it only have pass by value. 附带说明一下,C实际上没有“按引用传递”,它只有按值传递。 You emulate pass by reference by using pointers.
您可以通过使用指针来模拟按引用传递。
In your second version, string
itself is being passed by value, so you simply cannot change string
itself. 在第二个版本中,
string
本身是通过值传递的,因此您无法更改string
本身。 This is for the similar reason you cannot change the value of an int
or float
when it is passed by value. 出于类似的原因,当按值传递
int
或float
时,您无法更改它的值。 While an argument is being passed by value, there is a local copy created in the called function's stack. 当参数通过值传递时,在被调用函数的堆栈中创建了一个本地副本。
You can always change the content of string
, however. 但是,您始终可以更改
string
的内容。
In C, array type is represented as a pointer to its first element. 在C语言中,数组类型表示为指向其第一个元素的指针。
*
in type means "pointer to", but outside of type means "dereference pointer". *
in type表示“指向”的指针,而type之外则表示“取消引用指针”。 When you pass argument to function, in the body of function, you have copy of the thing, that you passed. 当您将参数传递给函数时,在函数主体中,您将获得传递的事物的副本 。 Lets analyse your code with that in mind:
让我们牢记这一点来分析代码:
void test(char **string) { //expect pointer to string
*string = (char *)malloc(5); //dereference pointer to string and allocate memory (*string is of type char*, it is a string)
char *temp = "hell"; //create new string
strcpy(*string, temp); //copy new string to the old one
}
int main(int argc, char *argv[]) {
char *string = NULL; //create empty pointer (string is array, which is pointer to char), but NULL is not a valid string
test(&string); //pass pointer to string
printf("%s\n", string); //print string
return 0;
}
**sting
did not change, but its contents *string
did. **sting
不变,但其内容*string
不变。 And in the second one: 在第二个中:
void test(char *string) { //with this type, you could modify, what is actual string content (for example first letter), but you pass here NULL, so there is nothing you can do
string = (char *)malloc(5); //here, you are changing only COPY of the pointer, that you passed in main
char *temp = "hell"; //create another string
strcpy(string, temp); //copy new string to the one created, after this operation pointer to the string is lost
}
int main(int argc, char *argv[]) {
char *string = NULL; //the same
test(string); //pass the string, you are screwed here, values in C are passed by copying, so even if you modify the string correctly, you will not see the result
printf("%s\n", string); //the string variable never changed from NULL, so you get the error
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.