【问题标题】:Modifying a string being passed as argument of a function in C [duplicate]在C中修改作为函数参数传递的字符串[重复]
【发布时间】:2018-06-26 02:29:49
【问题描述】:

如何修改在函数中作为参数传递的字符串的值

例如我有这个函数foo(应该将return_string的值从"old string"更改为"new string"):

int foo(char *return_string) {
    char *tmp = "new string";
    return_string = tmp;
    return 0;
}

但是如果我这样称呼它:

char *s = "old string";
foo(s);
printf("%s\n", s);

我仍然得到old string 作为输出。为什么?

我承认我对 C 中的指针和字符串有些困惑。

【问题讨论】:

标签: c string pointers


【解决方案1】:

问题

在函数foo()

int foo(char *return_string) {
    char *tmp = "new string";
    return_string = tmp;
    return 0;
}

您只是将指针 tmp 分配给指针 return_string。参数retrun_string 按值传递给foo()(即:它是调用者传递的内容的副本)。 return_string 指向的内容都没有被修改(这可能是您想要的),传递的指针也不会将修改保留在调用方。


strcpy()

考虑改用strcpy()

int foo(char *return_string) {
    char *tmp = "new string";
    strcpy(return_string, tmp);
    return 0;
}

这将修改return_string指向的字符串的内容。


通过引用传递指针

通过引用传递指针,可以修改指向字符串的指针:

int foo(char **return_string) {
    char *tmp = "new string";
    *return_string = tmp;
    return 0;
}

【讨论】:

  • return_string = &tmp; 应该是*return_string = tmp;
  • @mch tmp有自动存储时长,所以离开功能后不存在。这根本没有意义。
  • *return_string = tmp; 没问题,如果 tmp 指向字符串文字。使用&tmp 很危险。
  • 如果我通过引用传递指针,我应该以这种方式调用foo吗? char *s = "old string"; foo(&s); printf("%s\n", s);
  • 是的,为了通过引用传递指针s,使用foo(&s)(即:传递指针的地址)。
【解决方案2】:

您正在按值传递指针。您需要通过引用传递指针。

更改函数接口以传递char** return_string 而不是char* return_string。 然后做*return_string = tmp;

【讨论】:

    【解决方案3】:

    假设你的字符串是动态分配的,可能实现如下

    int foo(char **return_string) {
        if (*return string) free(*return_string)
        *return_string = strdup("new string");
        return 0;
    }
    
    char* s = strdup("original");
    foo(&s);
    ....
    

    【讨论】:

    • 不保证参数是动态分配的。
    • 试试char *test="hello"; foo(&hello); => 砰!在指针上传递指针时,调用者负责内存泄漏。
    • 当然可以。您需要就如何分配字符串达成一致。如果您使用动态分配,这是最通用的解决方案(您需要避免存储常量,但这不是最糟糕的限制。比如说,当您使用基于 strcpy 的方法时,您需要担心缓冲区大小。所有选项都有它们的缺点。最好的解决方案可能是您自己的带有显式释放器指针的字符串容器..但这可能超出了手头问题的范围。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 2020-09-20
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    相关资源
    最近更新 更多