也许是一个奇怪的问题..
我目前正在努力理解为什么以下等同于真,即“Hello World”打印到控制台?我一直认为C中的字符串比较必须使用 strcmp 或类似方法完成。
char *a = "Hello";
char *b = "Hello";
if(a == b)
{
printf("Hello World\n");
}
我还认为如果地址相同,这只会等同于真的吗?它们是文字吗?
PS。是的,这与作业几乎没有关系,但我只是想出了我的想法。 - 这不会以任何方式回答作业。
答案 0 :(得分:5)
该语言没有要求存储字符串文字的位置和方式。您所知道的是,它们具有静态存储持续时间,您不能尝试更改数据。标准中没有任何内容要求两个不同的字符串文字具有不同的地址,并且实现将重复删除字符串文字数据完全合理。
另一方面,没有什么要求将两个相同的字符串文字存储在同一个地址,因此在比较地址方面没有什么意义。始终使用strcmp
来比较字符串的内容。
答案 1 :(得分:3)
直接放入代码中的相同文字实际上会指向同一个内存位置以进行优化。
在这种情况下,编译器在固定内存中放下“Hello”一次,然后在该内存中指向a
和b
。
为了更详细地了解正在发生的事情,我建议你编译这个程序(首先添加一堆字符串文字),然后使用gdb
或valgrind或任何其他内存检查器并手动查看指向字符串文字的内存 - 你会发现在标准情况下gcc将所有字符串文字放在内存中并重新使用相同的字符串文字。
答案 2 :(得分:2)
a和b是指向字符的指针。
指针基本上存储内存地址。你的a和b变量不保存单词“hello”,但它们保存了保存单词“hello”的内存地址。
在程序中打印a和b以查看其值。
它看起来像:632176
或类似的东西,它们将是平等的。
所以代码a == b
基本上说:“a和b是否指向相同的内存地址?”。他们这样做,因为“hello”是一个常量字符串,它只会被写入内存一次。
答案 3 :(得分:1)
这里发生的事情是你有两个指针,分别叫*a
和*b
。接下来,如您所知,指针指向特定的内存位置。现在,当*a
和*b
都设置为完全相同的句子时,a
和b
指向内存地址。但是,编译器注意到指针是相同的句子,因此它将指向完全相同的内存地址以进行优化。
因此,会发生这样的事情:
a = 0xFFFFFFFF;
b = 0xFFFFFFFF;
if(0xFFFFFFFF == 0xFFFFFFFF){
// Code
}
现在比较它们时,编译器将其视为(0xFFFFFFFF == 0xFFFFFFFF)
编译器发现它们相等,导致if statement
变为真并显示Hello, World
但是,对于不同的编译器,这可能不会发生,因此您可能会在编译器之间获得不同的结果。这种行为确实适用于gcc。因此,在这种情况下,您应始终使用strcmp
进行比较,以避免此类随机行为。
答案 4 :(得分:1)
我相信如果你有两个指针指向一个相同值的指针,编译器只会将两个指针指向同一块内存。它更有效率。但是在C中,即使在这种情况下也总是使用strcmp。