我知道在C中比较“字符串”的正确方法是使用strcmp
,但现在我尝试将一些字符数组与==
运算符进行比较,并得到一些奇怪的结果。
看看以下代码:
int main()
{
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%d\n", s1 == s2); //1
printf("%d\n", s3 == s4); //0
printf("%d\n", s1 == s5); //0
}
第一个 printf
正确打印1
,表示它们不相等。但有人可以向我解释为什么在比较字符数组时,==
返回0
?
有人可以向我解释为什么第一个printf
返回1
(即它们相等)并且字符数组返回0
?
答案 0 :(得分:20)
==正在比较内存地址 您的编译器可能正在使s1和s2指向相同的静态数据以节省空间。
即。前两行代码中的“Andreas”存储在您的可执行数据中。 C标准说这些字符串是常量的,因此将两个指针指向同一个存储区。
char []行通过将数据复制到变量中来创建变量,因此在执行期间存储在堆栈的不同地址。
答案 1 :(得分:4)
呃...... ==
打印1时,表示 相等。它与strcmp不同,strcmp返回字符串的相对顺序。
答案 2 :(得分:2)
您正在比较地址而不是字符串。前两个是常量,只会创建一次。
int main()
{
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%d\n", s1 == s2); //1
printf("%p == %p\n", s1, s2);
printf("%d\n", s3 == s4); //0
printf("%p != %p\n", s3, s4);
printf("%d\n", s1 == s5); //0
printf("%p != %p\n", s1, s5);
}
我的电脑输出,但你明白了:
1
0x1fd8 == 0x1fd8
0
0xbffff8fc != 0xbffff8f4
0
0x1fd8 != 0x1fe0
答案 3 :(得分:1)
等一下...... 1表示真,0表示假。所以你的解释是部分倒退。至于为什么前两个字符串似乎相等:编译器只构建了一次常量字符串(s1 / 2)。
答案 4 :(得分:1)
s1 == s2
表示“(char*) == (char*)
”或地址相同。
s3 == s4
也是如此。那是工作中的“arrays decay into pointers”。
你有比较结果错误的含义:
0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */
答案 5 :(得分:1)
从s1到s5的所有值都不是 char 本身,它们指向 char 。所以你要比较的是每个字符串的内存地址,而不是字符串本身。
如果显示地址,您可以看到比较运算符实际上在做什么:
#include <stdio.h>
int main() {
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%p\n", s1); // 0x80484d0
printf("%p\n", s2); // 0x80484d0
printf("%p\n", s3); // 0xbfef9280
printf("%p\n", s4); // 0xbfef9278
printf("%p\n", s5); // 0x80484d8
}
在内存中分配字符串的确切位置是特定于实现的。在这种情况下,s1和s2指向相同的静态内存块,但我不希望这种行为是可移植的。
答案 6 :(得分:0)
您无法比较字符串,但可以比较指针。