代码之家  ›  专栏  ›  技术社区  ›  Walid Beydoun

为什么在C样式字符串上使用==有效?

  •  3
  • Walid Beydoun  · 技术社区  · 10 年前

    我的印象是,比较运算符不是为C样式字符串定义的,这就是为什么我们使用 strcmp() 。因此,以下代码在C和C++中是非法的:

    if("foo" == "foo"){
        printf("The C-style comparison worked.\n");
    }
    
    if("foo" == "bob"){
       printf("The C-style comparison produced the incorrect answer.\n");
    } else {
       printf("The C-style comparison worked, strings were not equal.\n");
    }
    

    但我在使用GCC的代码块和VS2015中测试了它,分别编译为C和C++。两者都允许代码并产生正确的输出。

    比较C型字符串合法吗?或者它是一个非标准编译器扩展,允许此代码工作?

    如果这是合法的,那么人们为什么使用 strcmp() 在C中?

    3 回复  |  直到 7 年前
        1
  •  12
  •   rems4e    10 年前

    编译器可以自由使用字符串实例化,即通过避免重复相同的数据来节省内存。2 "foo" 在您的情况下,比较相等的文字必须存储在相同的内存位置。

    然而,你不应该把这当作规则。这个 strcmp 该方法在所有情况下都可以工作,而您的观察是否适用于其他编译器、编译器版本、编译标志集等则由实现定义。

        2
  •  11
  •   P.P    10 年前

    该代码在C语言中是合法的,它可能不会产生您期望的结果。

    字符串文本的类型为 char[N] 在C和 const char[N] 在C++中,其中N是字符串文本中的字符数。 "foo" 是类型 char[4] const char[4] 分别用C和C++编写。基本上这是一个 大堆 当数组用于 表示 因此在比较中, if("foo" == "foo") 字符串文字被转换为指针。因此,“地址比较”。

    在比较中,

    if("foo" == "foo"){
    

    比较字符串文字的地址,这些地址可能相等,也可能不相等。

    它相当于:

    const char *p = "foo";
    const char *q = "foo";
    
    if ( p == q) {
     ...
     }
    

    C标准不能保证具有相同内容的两个字符串文字的地址相等( “foo” 在这里)放置在同一位置。但实际上,任何编译器都会放在同一地址。因此,这种比较似乎有效。但你不能依赖这种行为。

    6.4.5,字符串文字 ( C11, draft )

    如果这些阵列具有 元素具有适当的值。如果程序试图 修改这样的数组,行为是未定义的。

    同样,这种比较

    if("foo" == "bob"){
     ...
    }
    

    相当于:

    const char *x = "foo";
    const char *y = "bob";
    
    if("foo" == "bob"){
      ...
    }
    

    在这种情况下,字符串文本将位于不同的位置,指针比较失败。因此,在这两种情况下 == 运算符实际上用于比较C字符串。

    相反,如果您使用 阵列 ,它将不起作用:

    char s1[] ="foo";
    char s2[] = "foo";
    
    if (s1 == s2) {
      /* always false */
    }
    

    不同的是,当用字符串文字初始化数组时 复制 到阵列中。阵列 s1 s2 地址不同,永远不会相等。但对于字符串文字 p q 指向相同的地址(假设编译器是这样放置的-如上所述,这是不保证的)。

        3
  •  0
  •   user3629249    10 年前

    它是复制/比较字符串的地址,而不是字符串的内容。

    比较地址是有效的操作