【问题标题】:Comparing String if( "bonaparte"=="bonaparte" ) this gives true result?比较 String if( "bonaparte"=="bonaparte" ) 这给出了真实的结果?
【发布时间】:2021-05-08 03:19:08
【问题描述】:

注意:我知道我可以通过使用 strcmp() 来做这些事情,但我只是在尝试等于 == 运算符。

代码 1:

#include<stdio.h>

int main()
{
    char s1[]="bonaparte",s2[]="bonaparte";
    
    if(s1==s2)
    {
        printf("True");
    }
    else
    {
        printf("Flase");
    }
    
}

输出:

False

代码 2:

#include<stdio.h>

int main()
{
    char s[]="bonaparte";
    
    if(s=="bonaparte")
    {
        printf("True");
    }
    else
    {
        printf("Flase");
    }
    
}

输出:

False

代码 3:

#include<stdio.h>

int main()
{
    
    if("bonaparte"=="bonaparte")
    {
        printf("True");
    }
    else
    {
        printf("Flase");
    }
    
}

输出:

True

所以,在#1 中,我们比较了s1s2 的基地址,显然它们会有所不同,因此输出为“False”。

在#2 中,我们比较了s 的基地址和常量字符串"bonaparte" 的基地址,显然它又会有所不同,因此输出为“False”。

然而,在#3 中,我们比较了一个常量字符串"bonaparte" 和另一个常量字符串"bonaparte" 的基地址。我认为字符串名称是相同的,但它们会在内存中获得不同的位置,因此,当我们尝试比较它们的基地址时,它们应该是不同的。但输出与上述矛盾(我认为)。

那么在第 3rd 案例中究竟发生了什么?

【问题讨论】:

  • but they will get different location in memory 为什么编译器会将此(只读)数据存储两次?会浪费空间。
  • 字符串文字可能只有一个副本,但您不能指望它。 strcmp 和朋友的存在是有原因的。

标签: c string compare


【解决方案1】:

在编译您的第三个代码示例时,编译器会应用通常称为“字符串池”的方法——也就是说,编译器会发现两个(或更多)字符串字面量相同,因此无法在运行时更改这些常量, 通过仅生成一个数据实例来优化代码,因此这两个文字最终具有相同的地址。

大多数编译器默认执行此操作,但您可以禁用它。例如,在带有 MSVC 编译器的 Visual Studio 中,您可以设置 /GF- 选项来禁用它。有了这个集合,上面的代码将“Flase”(sic)作为输出(Reference)。

【讨论】:

  • 非常感谢,您知道如何在 DEV C++ 中禁用它
  • @AbhishekMane 不完全确定,但 IIRC Dev-C++ 在内部使用 GCC 编译器。如果是这样,编译选项 -fno-merge-constants 可能是您需要的,和/或关闭所有优化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
相关资源
最近更新 更多