执行字符串方法时出现意外输出

时间:2013-08-30 18:52:18

标签: c

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

int main()
{
  static char s1[]="Good";
  static char s2[20];
  static char s3[20]="Day";

  int i = strcmp(strcat(s3,strcpy(s2,s1)),strcat(s3,"good"));

  printf("%d\n",i);

  return 0;
}

这里输出为0,这意味着作为strcmp的参数传递的两个字符串是相等的。但对于strcmp,第一个参数是"DaygoodGood",第二个参数是"Daygood" ...

为什么会这样?

4 个答案:

答案 0 :(得分:4)

您正在将s3s3进行比较,无论您如何看待它。这样做你总能做到平等。打破它 - 改变:

    i=strcmp(strcat(s3,strcpy(s2,s1)),strcat(s3,"good"));

成:

    char *s4 = strcpy(s2,s1);     // s4 == s2 -> "Good"
    char *s5 = strcat(s3,s4);     // s5 == s3 -> "DayGood"
    char *s6 = strcat(s3,"good"); // s6 == s3 -> "DayGoodgood"

    i = strcmp(s5, s6);           // same as strcmp(s3, s3)

现在真的是否以这种方式发生,或者如果它是:

    char *s4 = strcpy(s2,s1);     // s4 == s4 -> "Good"
    char *s6 = strcat(s3,"good"); // s6 == s3 -> "Daygood"
    char *s5 = strcat(s3,s4);     // s5 == s3 -> "DaygoodGood"

    i = strcmp(s5, s6);           // same as strcmp(s3, s3)

相反,标准未指定。无论如何,您要比较相同的字符串,无论这些字符串发生在哪个顺序。您要么将"DayGoodgood""DayGoodgood""DaygoodGood""DaygoodGood"进行比较,但您应该期望{结果为{1}}。

答案 1 :(得分:3)

strcat(t, s)结果始终等于t。如果您发现这一点令人困惑,请记住C中的字符串是字符指针,因此我们讨论的是两个指针相等,而不是字符串t的(先前或当前)内容。

因此,比较的两个字符串是s3s3,无论当时s3包含什么。当然他们是平等的。

答案 2 :(得分:1)

这是因为第一个strcat会返回s3,就像第二个一样。第一次调用会向s3的内容添加内容,第二次追加更多内容,但两者都会返回相同的指针。

答案 3 :(得分:1)

首先,谢谢你提出这个问题。它实际上比人们第一眼看上去更复杂。

要理解的第一个概念是“副作用”。也就是说,当一个参数调用一个函数时,该函数可能会修改数据,以便修改参数的计算方式。

例如,在评估strcmp(A,B)首先评估哪个参数时,A还是B?如果A和B只是变量,则 NOT 不重要。但是,如果它们本身就是函数,则可能很重要:strcmp(A(1), B(2))如果首先评估A(1)或B(2),它可能/可能会有所不同。

让我们专门看一下你的代码:

 strcmp(strcat(s3,strcpy(s2,s1)),strcat(s3,"good"));

编译器可以在内部对其进行评估:

 A)
    strcat(s3,strcpy(s2,s1));  //s3 = "DayGood'
    strcat(s3,"good");         //s3 = "DayGoodgood"
    strcmp(s3, s3);

或者它可以评估为:

 B)
    strcat(s3,"good");         // s3 = "Daygood"
    strcat(s3,strcpy(s2,s1));  // s3 = "DaygoodGood"
    strcmp(s3, s3);

因此,s3有两个可能的值,取决于编译器如何评估参数,差异是“副作用”的证据。

最后,要确切了解编译器的工作原理,请修改printf语句:

  printf("\n%d, %s\n\n", i, s3);

希望这有帮助。