为什么单指针作为参数不能修改字符串(在 c 中)

Why single pointer as argument can't modify a string (in c)

提问人:Fary 提问时间:4/21/2023 最后编辑:Vlad from MoscowFary 更新时间:4/21/2023 访问量:87

问:

通过在函数中使用双指针作为参数,下面的程序可以修改字符串,我理解。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void display(char** output)
{
    printf("%s\n", *output);
    *output = "This is another test";
}

int main(void)
{
    char* str = "This is a test";
    display(&str);
    printf("After the call: %s\n", str);
    return 0;
}

但是,我不明白为什么使用单个指针作为参数(如下所示)不能修改字符串。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void display(char* output)
{
    printf("%s\n", output);
    output = "This is another test";
    printf("%s\n", output);
}

int main(void)
{
    char* str = "This is a test";
    display(str);
    printf("After the call: %s\n", str);
    return 0;
}
C 引用传递 按 值传递 双指针

评论

2赞 wohlstad 4/21/2023
在 c 中,参数始终按值传递。在第 2 个中,您传递指针本身。它是按值传递的,因此更改 in 会修改副本,并且不会影响调用方。在第 1 个中,您仍然按值传递(一如既往),但传递指针的地址。使用地址,您可以修改调用方的指针 ()。outputfunc*output = ...
0赞 Fary 4/21/2023
为什么可以使用函数中指针的地址来修改指针?
1赞 Lundin 4/21/2023
stackoverflow.com/questions/39486797/...,答案就解释了。
1赞 Aconcagua 4/21/2023
请注意,在 C 语言中,所有参数都按值传递给函数。这意味着这些值将被复制。总是,句号。这也适用于指针。因此,如果在第二个示例中指定参数,则修改副本。这也适用于双指针,如果您不取消引用它。在取消引用时,您修改此双指针指向 - 这是函数外部的单指针...
1赞 Aconcagua 4/21/2023
请注意,尽管是合法的,但您永远不应该将字符串文本分配给指向非常量字符的指针!这样一来,你就有可能意外地修改它们,这是未定义的行为。如果你的代码变得复杂,你总有一天会这样做......

答:

1赞 jingwei jiang 4/21/2023 #1

不能在函数中分配参数。

void func(int* a) {
    int b = 0;
    *a = b; // that'll work.
    a = &b; // that doesn't.
}

使用 a 做你想做的事。char**

评论

1赞 Lundin 4/21/2023
“不起作用”并不能解释为什么,是......
4赞 Vlad from Moscow 4/21/2023 #2

您可以按以下方式想象第二个所示程序中的函数及其调用

char* str = "This is a test";
display(str);

//...

void display( /* char* output */ )
{
    char *output = str;

    printf("%s\n", output);
    output = "This is another test";
    printf("%s\n", output);
}

也就是说,参数表达式是用来初始化函数局部变量的。在函数中,正在更改的是它的局部变量。用作函数局部变量初始值设定项的指针保持不变。该函数除了使用它来初始化其参数外,不处理。stroutputoutputstrstroutput

要更改函数中的对象,您需要通过引用将其传递给函数。

在 C 语言中,通过引用传递意味着通过指向对象的指针间接传递对象。因此,取消引用指针后,函数可以直接访问指针指向的对象,并可以更改它。您的第一个程序演示了这种方法。

取消引用指针output

*output = "This is another test";

该函数可以直接访问在 main 中声明的指针,并通过指向该函数的指针传递给该函数str

display(&str);

并改变它。

评论

0赞 Fabio says Reinstate Monica 4/21/2023
不过,它不是 UB,因为代码修改了 using 而不是 ?char *char []
1赞 Vlad from Moscow 4/21/2023
@FabiosaysReinstateMonica 该函数不会更改任何字符串文本。它更改指针本身的值。字符串文字保持不变。
0赞 Fabio says Reinstate Monica 4/21/2023
啊,你是对的,对不起!