2016-06-13 47 views
0

考虑以下两个代码字符串:
比较使用memcmp在C

char str1[] = "Hello"; 
char str2[] = "Hello\0\0\0l\0o"; 
int x; 
x=memcmp(str1,str2,sizeof(str2)); 
printf("%d",x); 

当我运行它,它显示了O/P为:

1 

你能解释的理由这个。我了解到两个字符串中的每个字节都会进行比较并相应返回。但我不清楚最后会发生什么。

+0

你确定'str1 []'和'str2 []'没有任何大小? –

+0

您是否考虑在您的初学者C书中阅读关于memcmp的内容?除了你的代码中的错误之外,你的问题的答案可以在那里找到。 – Lundin

回答

6

您的程序调用未定义的行为。

sizeof(str2)大于sizeof(str1)。通过使用它作为memcmp的最后一个参数,您正在访问您不应该访问的内存。这是未定义行为的原因。

因此,输出可以是任何东西。试图理解它毫无意义。

3

当你做字符串比较时,一旦它达到'\ 0'就会停止比较。在这里你已经完成了一个memcmp,它不会停止,直到读取所有请求的字符。

在这种情况下,你要比较sizeof(str2)字节,在str1的情况下,在末尾隐含的'\ 0'后会产生垃圾。

要在比较得到一个0:

  • 只比较的sizeof(STR1)或的sizeof(STR1)+1个字节
  • 做一个字符串比较
1

请记住,这是不安全有时危险在这里调用memcmp因为str1长度比str2少。

考虑下面的代码:

int main() 
{ 
    char str1[] = "Hello"; 
    char str2[] = "AAAAA\0\0\0l\0o"; 
    for(int i=0; i<sizeof(str2); i++) 
     printf("%02X %02X\n", str1[i], str2[i]); 
    printf("\n%X %X", (int)str1, (int)str2); 
    return 0; 
} 

输出是

48 41 
65 41 
6C 41 
6C 41 
6F 41 
00 00 
41 00 
41 00 
41 6C 
41 00 
41 6F 
00 00 

28FEEE 28FEF4 

我们可以看到[6] - [11]个字节的str1实际上是str2第一个字节,它可以通过str1str2的地址确认。在这种情况下,GCC/MSVC(我对Clang不太确定)将两个字符串const initalizer存储在一行中。因此,当您拨打memcmp时,在空终止符\0后,该函数实际上将str2的第一个字节与\0进行比较。但请记住,编译器存储常量的方式在任何情况下都可能会改变。你应该不是依靠这种行为。