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

时间:2015-09-28 06:22:42

标签: c string

我通过使用一个非常简单的程序熟悉c-strings和指针。

此版本通过引用传入字符串,起作用:

#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;
}

打印“地狱”。

此版本只是按值传递字符串,不起作用,并产生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;
}

据我所知,第一个版本有意义,因为我传入了字符串地址的地址。因此,当我取消引用这个双指针时,我得到字符串的真实地址,并可以用malloc重新分配它。

然而,第二个版本,我有点不清楚为什么它不起作用。在这个版本中,我将字符串的地址传递给测试函数。我读到C中的所有内容都是按值传递的,但数组名称实际上是地址。这是不是意味着我将字符串的实际地址传入测试?不应该有相同的事情吗?我很困惑,请帮帮我。

4 个答案:

答案 0 :(得分:3)

记住这一点:在C编程中使用一个值,你传递&#34;按值&#34;。要更改值,您必须通过&#34;地址&#34;。因此,如果您要更改的是地址,则需要传递其地址以进行更改。否则您只能使用它。

答案 1 :(得分:2)

当您通过“按值”传递参数时,参数的值将复制到函数中的形式参数中。更改副本(在string函数中的test个案例中)当然不会更改原始文件(string函数中的main)。

在旁注中,C实际上没有“按引用传递”,它只传递值。您使用指针模拟通过引用传递。

答案 2 :(得分:0)

在您的第二个版本中,string 本身正在按值传递,因此您无法自行更改string。这是出于类似的原因,当您按值传递时,您无法更改intfloat的值。当一个参数按值传递时,会在被调用函数的堆栈中创建一个本地副本。

但是,您始终可以更改string的内容。

答案 3 :(得分:0)

在C中,数组类型表示为指向其第一个元素的指针。类型中的*表示&#34;指向&#34;的指针,但在类型之外表示&#34;取消引用指针&#34;。当您将参数传递给函数时,在函数体中,您已经传递了事物的 copy 。让我们分析你的代码:

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没有改变,但其内容*string没有改变。 在第二个:

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;
}