为什么C中的"a"!="a"?

Jav*_*ram 110 c string

void main() {
    if("a" == "a")
      printf("Yes, equal");  
    else
      printf("No, not equal");
}
Run Code Online (Sandbox Code Playgroud)

为什么输出No, not equal

Tim*_*per 209

您要比较的是不同字符串的两个内存地址,它们存储在不同的位置.这样做基本上是这样的:

if(0x00403064 == 0x002D316A) // Two memory locations
{
    printf("Yes, equal");
}
Run Code Online (Sandbox Code Playgroud)

使用以下代码比较两个字符串值:

#include <string.h>

...

if(strcmp("a", "a") == 0)
{
    // Equal
}
Run Code Online (Sandbox Code Playgroud)

另外,"a" == "a"可能确实返回true,具体取决于您的编译器,它可能在编译时将相等的字符串组合成一个以节省空间.

当您比较两个字符值(不是指针)时,它是一个数字比较.例如:

'a' == 'a' // always true
Run Code Online (Sandbox Code Playgroud)

  • GCC还有选项`-fmerge-constants`和`-fno-merge-constants`来启用/禁用跨转换单元的字符串和浮点常量合并,尽管在某些GCC上似乎始终启用常量合并,无论如何选项. (12认同)
  • 如果你使用'a'而不是'a',它会工作.第一个是char,它实际上是一个数值. (2认同)

eq-*_*eq- 52

我参加聚会有点晚了,但无论如何我都会回答.技术上相同的比特,但是从一个不同的角度(C用语如下):

在C中,表达式"a"表示字符串文字,这是一个静态无名阵列const char,具有二的长度-阵列由字符'a''\0'-终止空字符信号的字符串的末尾.

但是,在C中,您无法通过值将数组传递给函数 - 或者为它们赋值(在初始化之后) - ==数组没有重载运算符,因此无法直接比较它们.考虑

int a1[] = {1, 2, 3};
int a2[] = {3, 4, 5};
a1 == a2 // is this meaningful? Yes and no; it *does* compare the arrays for
         // "identity", but not for their values. In this case the result
         // is always false, because the arrays (a1 and a2) are distinct objects
Run Code Online (Sandbox Code Playgroud)

如果==不是比较数组,它实际上做了什么呢?在C中,在几乎所有的上下文中 - 包括这一个 - 数组衰减成指针(指向数组的第一个元素) - 并且比较指针的相等性就是你所期望的.这样做有效

"a" == "a"
Run Code Online (Sandbox Code Playgroud)

实际上,您正在比较两个未命名数组中第一个字符的地址.根据C标准,比较可以产生真或假(即1或0) - "a"s实际上可以表示相同的阵列或两个完全不相关的阵列.在技​​术术语中,结果值是未指定的,这意味着允许比较(即,它不是未定义的行为或语法错误),但任何一个值都是有效的,并且不需要实现(您的编译器)来记录实际发生的情况.

正如其他人所指出的,为了比较"c字符串"(即以空字符结尾的字符串),您可以使用strcmp标准头文件中的便捷功能string.h.该函数具有0相等字符串的返回值; 明确地比较返回值0而不是使用运算符`!',即

strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)
Run Code Online (Sandbox Code Playgroud)


Pra*_*rav 47

根据C99(第6.4.5/6节)

字符串文字

如果这些数组的元素具有适当的值,则这些数组是否不同是未指定的.

因此,在这种情况下,未指明两者"a"是否不同.优化的编译器可以将单个保留"a"在只读位置,并且两个引用都可以引用它.

这里查看gcc的输出


Ant*_*udt 19

因为它们是2个独立const char*的指针,没有实际值.你在说什么0x019181217 == 0x0089178216当然会返回NO

strcmp()而不是==

  • 字符串文字不是指针,它们是数组.尽管如此,他们还是会在比较中衰败. (7认同)

Jon*_*ood 9

简单地说,C没有内置的字符串比较运算符.它无法以这种方式比较字符串.

相反,使用标准库例程(如strcmp())或通过编写代码来循环字符串中的每个字符来比较字符串.

在C中,双引号中的文本字符串返回指向字符串的指针.您的示例是比较指针,显然您的两个版本的字符串存在于不同的地址.

但是,正如您所期望的那样,它并不是在比较字符串本身.