Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在C样式的字符串上使用==有效?_C++_C_Gcc_Visual Studio 2015_Strcmp - Fatal编程技术网

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

C++ 为什么在C样式的字符串上使用==有效?,c++,c,gcc,visual-studio-2015,strcmp,C++,C,Gcc,Visual Studio 2015,Strcmp,我的印象是比较运算符不是为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("T

我的印象是比较运算符不是为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和VS 2015在两个代码块中测试它,编译为C,也作为C++。两者都允许编写代码并生成正确的输出

比较C样式字符串合法吗?或者是允许此代码工作的非标准编译器扩展


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

编译器可以自由地使用字符串插入,即通过避免重复相同的数据来节省内存。比较相等的2
“foo”
文本必须存储在案例中的相同内存位置


但是,您不应该将此作为规则。
strcmp
方法在任何情况下都可以工作,但是它是由实现定义的,您的观察是否适用于另一个编译器、编译器版本、编译标志集等。

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

<> >字符串类型的类型是C和<代码> >代码> > const char [n] < /c> C++中,其中n是字符串文字中的字符数。 <代码>“FoO”<代码>是C和C++中的类型<代码> char [4 ] < /> >和<代码> const char [4 ] < /C>。基本上它是一个数组。在表达式中使用时,数组将转换为指向其第一个元素的指针。因此在比较中,
if(“foo”==“foo”)
字符串文本被转换为指针。因此,“地址比较”

相比之下

if("foo" == "foo"){
比较字符串文本的地址,这些地址可能相等,也可能不相等

这相当于:

const char *p = "foo";
const char *q = "foo";

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

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

6.4.5,字符串文字()

未指定这些数组是否不同,前提是它们的 元素具有适当的值。如果程序试图 如果修改这样的数组,则行为未定义

同样,这种比较

if("foo" == "bob"){
 ...
}
相当于:

const char *p = "foo";
const char *q = "foo";

if ( p == q) {
 ...
 }
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
都指向相同的地址(假设编译器如此放置-这不保证如上所述)。

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


比较地址是有效的操作

代码是合法的。它只是进行指针比较,这可能不是您想要的
strcmp()
实现了大多数人所期望的功能—它比较字符串的内容,而不仅仅是第一个元素的地址。对于您的代码,
“foo”==“foo”
的结果是实现定义的。好吧,这很有意义。然后假设我定义了两个“向量”,并用相同的字符串填充它们。如果我使用通用算法“equal”来比较这两个容器,我仍然会得到正确的答案。相等比较容器,char*指针不可能指向内存中相同的位置,如果它们来自两个不同的向量,可以吗?它们完全可以指向相同的内存。它们毕竟只是指针。如果将指针本身从一个向量复制到另一个向量,那么它将引用相同的内存,对吗?分配字符串文本也是如此,因为它们在分配时会衰减为指针值。现在清楚了吗?是的,谢谢你的帮助。总有一天,我会把我的头绕在指针上,完全理解它们。干杯,伙计。你的
p
q
示例可能有效,也可能无效<代码>字符pp[]=“foo”;char*p=pp,等等将保证它将作为不同的对象进行比较。@Matsson我只是想添加一个带有数组的示例。但是
p
q
完全等同于直接比较字符串文本。(这两种比较方法可能有效,也可能无效)。@Mats-peterson——最重要的是,它可能有效,也可能无效,与最初的例子完全相同。p&q代码在功能上是等效的。我认为这里是解释为什么字符串文字有效地“衰减”到指针的恰当时机:除非它是
sizeof
运算符的操作数、
\u Alignof
运算符或一元
&
运算符,或者是用于初始化数组的字符串文字,类型为“类型的数组”的表达式被转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素,并且不是左值。@Andrewenle我为其添加了一点解释。希望现在好多了。