简体   繁体   English

为什么必须通过引用传递字符串才能更改其指向的位置?

[英]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. 出于类似的原因,当按值传递intfloat时,您无法更改它的值。 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.

相关问题 如何更改 function 内的节点指向的位置 - How can I change where a node points inside a function 函数何时必须通过引用接收自变量以更改自变量? - When must a function receive an argument by reference in order to change something about the argument? 我该如何更改通过一个指针填充该字符串,该指针指向另一个指针,然后该指针指向该字符串 - How do I change fill this string through a pointer which points to another pointer which then points to this string C通过引用字符串传递 - C Pass by reference string 如何传递对字符串的引用? - How to pass a reference to a string? 在C中通过引用递归传递字符串 - Pass string by reference recursively in C 为什么gtk +通过引用传递? - Why gtk+ pass by reference? 如何更改通过引用传递给函数的字符串的值? - How do I change the value of a string passed by reference to a function? 为什么我不能引用以前转换为void的字符串中的字符? - Why can't I reference a character in a string that was previously cast to void? 我试图创建一个程序来反转字符串,如果字符串是大写的,我必须在 c 中将其更改为小写,反之亦然 - im trying to create a program to reverse a string and if the string has uppercase i must change it to lowercase and vice versa in c
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM