【发布时间】:2013-07-27 21:39:46
【问题描述】:
在使用 C 指针文献来磨练我的 C 技能的过程中,我遇到了这段代码。在这个问题中,我应该证明输出的合理性。我熟悉strcat() 和strcmp() 的工作。我知道strcmp() 在两个字符串传递时返回 0,它们是相同的。
# include <stdio.h>
# include <string.h>
int main()
{
static char str1[]="Good";
static char str2[20];
static char str3[20] ="Day";
int l;
l = strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good"));
printf("%d\n", l);
return 0;
}
提供的答案是 0,这意味着两个计算的字符串必须相同。我试图通过多个步骤解决该语句。
首先,尝试strcat(str3, strcpy(str2, str1))。
'str2' 更改为 "Good",然后 strcat() 将 str3 更改为 `DayGood'。
到目前为止,我的 gcc 编译器与我一致。
来到strcat(str3, "good"),由于str3 已经更改为DayGood,strcat 将str3 更改为DayGoodgood。
再次,gcc 与我发生冲突。
int main()
{
static char str1[]="Good";
static char str2[20];
static char str3[20] ="Day";
int l;
printf("%s\n", strcat(str3, strcpy(str2, str1)));
printf("%s\n", strcat(str3, "good"));
//l = strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good"));
//printf("%d\n", l);
return 0;
}
它产生
DayGood
DayGoodgood
我再次尝试了这种变化。
int main()
{
static char str1[]="Good";
static char str2[20];
static char str3[20] ="Day";
int l;
printf("%s\n", strcat(str3, "good"));
printf("%s\n", strcat(str3, strcpy(str2, str1)));
//l = strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good"));
//printf("%d\n", l);
return 0;
}
它产生。
Daygood
DaygoodGood
在我的两个测试用例中,我得到了两个不同的字符串进行比较。那么为什么 strcmp() 会产生 0 呢?
【问题讨论】:
-
到处都是各种未定义和未指定的行为,甚至不要试图推理他们......
-
我不确定有什么未定义的。
str3的最终内容可能取决于未指定的评估顺序,但未知顺序的函数调用并不像x=x++那样糟糕,而且我认为任何可能的顺序都不会溢出缓冲区。重要的事实是str3最终等于它自己。 -
@WumpusQ.Wumbley
str3的内容在序列点之间被多次修改。 -
@H2CO3 我相信内部
strcat的完成提供了一个序列点,它的副作用在外部调用之前提交。 -
至少我们可以非常确定,编写此代码的人打算将其作为一个技巧问题......“发现无序的函数调用”或“注意到字符串等于自身”。它肯定不会教如何正确使用字符串函数