C++ 为什么在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
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我为其添加了一点解释。希望现在好多了。