字符串修改函数:返回void还是char*?

3

例如:

void foo1(char *buffer) {
    buffer[0] = 'a';
}

char *foo2(char *buffer) {
    buffer[0] = 'a';
    return buffer;
}

当我想修改一个字符串时,可以这样做:
mystr[] = "foobar";
foo1(mystr);
printf("%s",mystr);

或者使用返回值:

mystr[] = "foobar";
char *mystr2;
mystr2 = foo2(mystr);
printf("%s",mystr2);

我对第二种方法有些困惑:mystr和mystr2指向不同的位置,但保存着相同的字符串。我原以为foo2返回时会将修改后的mystr的地址复制到mystr2,但实际发生了什么?

第二个问题是:哪种方式修改字符串更加标准?


1
在第二个例子中,mystr 被修改了,而 mystr2 指向了 mystr。尝试也打印出第二个例子中的 mystr - Some programmer dude
不够清晰,而且范围太广。每个问题只提一个问题。 - too honest for this site
1
关于您的第二个问题,答案是:两者皆可或都不行。哪一个“最好”(高度主观)取决于您的使用情况。使用第二个选项,例如 printf("%s", foo2(mystr)) 在某些情况下可能很有用,但在其他情况下则不然。 - Some programmer dude
3
@Olaf - 这个问题已经很清楚了,而且非常相关,不会违反你引用的任何规则。 - ryyker
在“分级”时,这个问题出现了,作为一个“好”的问题测试;但我实际上同意@ryyker的观点;因此我在meta上提出了一个关于这个问题的问题(http://meta.stackoverflow.com/questions/342059/is-this-is-a-good-example-for-triage-test)……所以当突然出现负投票、正投票、关闭投票时,请不要感到惊讶。 - GhostCat
显示剩余2条评论
2个回答

4
哪种修改字符串的方法更标准?
在头文件 <string.h> 中声明的标准 C 字符串函数通常返回指向目标字符串的指针。这样可以将字符串函数链接在一起。例如,相对于您的第二个函数定义,您可以编写以下代码:
printf("%s", foo2(mystr));

该语句输出修改后的源字符串。

在这段代码片段中

char mystr[] = "foobar";
char *mystr2;
mystr2 = foo2(mystr);
printf("%s",mystr2);

作为参数传递给函数的字符数组mystr[]会被隐式转换为指向其第一个字符的指针。并且从被调用的函数返回的同一地址是数组第一个字符的指针。因此,在这个语句之后:
mystr2 = foo2(mystr);

指针 mysstr2 也指向字符数组 mystr 的第一个字符。
函数 printf 可以使用以下两种方式调用:
printf("%s",mystr);

或者像这样
printf("%s",mystr2);

因为在两种情况下都将相同的地址传递给函数,而且在第一种情况下传递给函数printf的字符数组被隐式转换为指向其第一个字符的指针。


1
我建议
char *foo( char *str );

您可以始终忽略返回值,这更加灵活。您不能使用。
void foo( char *str );

作为函数参数:
int someFunc( char *val );
...
int rc = someFunc( foo( data ) );

使用返回指针的函数结果作为函数参数可能非常糟糕。而且也相当丑陋,使得代码更难读,并且其他问题也会出现。我不理解为什么一些程序员如此在乎让代码变得不可读。比如说“减少变量”,这有什么好处呢? - Iharob Al Asimi
2
让我们考虑strcat。从可读性的角度来看,我们宁愿不使用它:print(a + b)。但在C语言中,我们别无选择,必须写成strcat(a,b)。现在,如果strcat是一个void函数,我们就必须写成:strcat(a,b); print(a) 看到问题了吗?意图在这里并不是非常清晰。我们确切地写出了我们如何做事情,但我们正在做什么必须被重新构建。而print(strcat(a,b))更接近于表达我们正在尝试做什么。 - user3458
1
点赞这个答案:它恰好回答了问题,没有太多的废话。 - linuxfan says Reinstate Monica
1
@IharobAlAsimi 使用返回指针的函数结果作为函数参数可能非常糟糕。而且也相当丑陋 这只是灵活性返回char *提供的一个例子。返回char *允许函数执行所有 void函数所做的事情 - 然后更多。 - Andrew Henle
同@linuxfan的评论。清晰简洁。 - ryyker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接