string文字的C ++比较
我是一个C + +新手(只是老式C)。 我的儿子请求帮助,我无法解释它。 如果他问我“如何比较string”,我会告诉他使用strcmp(),但这并不是什么混淆我。 这是他问的问题:
int main() { cout << ("A"< "Z"); }
将打印1
int main() { cout << ("Z"< "A"); }
也会打印1,但是
int main() { cout << ("Z"< "A"); cout << ("A"< "Z"); }
然后将打印10.单独这两个cout语句打印1,但连续执行我得到不同的答案?
您正在比较内存地址。 显然你的编译器把string文字按照遇到它们的顺序放到内存中,所以第一个比第二个“小”。
由于在第一个片段中,首先看到“A”,然后看到“Z”,则“A”更小。 由于第二次看到“Z”,所以“Z”较小。 在最后一个片段中,当第二个命令滚动时,它已经放置了文字“A”和“Z”。
string文字具有静态存储持续时间。 在所有这些比较中,都比较了编译器为string文本分配的内存地址。 看起来,编译器遇到的第一个string字面值与下一个遇到的string字面值相比存储在地址较低的内存中。
因此在这个程序中
int main() { cout << ("Z"< "A"); cout << ("A"< "Z"); }
string文字“Z”全部位于比string文字“A”更低的地址处,因为它是编译器首先find的。
考虑到这个比较
cout << ("A"< "A");
可以给出不同的结果,具体取决于编译器的选项,因为编译器可以为string文本分配两个内存区域,也可以只使用一个相同的string文本副本。
从C ++标准(2.14.5string文字)
12是否所有string文字都是不同的(即,是否存储在非重叠对象中)是实现定义的。 尝试修改string文字的效果是未定义的。
这同样适用于C.
在声明中:
cout << ("A"< "Z");
你已经创build了2个string文字 : "A"
和"Z"
。 这些types是const char *
,它是一个指向空终止字符数组的指针。 这里的比较是比较指针而不是它们指向的值。 这是内存地址比较这是什么给你的编译器警告。 比较的结果是由编译器分配内存的位置决定的,编译器和编译器之间的内存有些随意。 在这种情况下,它看起来像find的第一个文字是由您的编译器分配第一个内存地址。
就像在C中正确地比较这些string文字一样,您需要使用strcmp
来进行值的比较。
但是,当你用更习惯的c ++方法做一些事情时:
cout << (std::string("A") < std::string("Z"));
然后你得到正确的比较值作为比较运算符为std::string
定义。
如果你想比较实际的C ++string,你需要声明C ++string:
int main() { const std::string a("A"); const std::string z("Z"); cout << (z < a) << endl; // false cout << (a < z) << endl; // true }
在C ++中,结果是未指定的。 我将为C ++ 11使用N3337 。
首先,我们必须看看string文字的types是什么。
§2.14.5
9
普通string文字和UTF-8string文字也被称为窄string文字。 窄string常量的types为“ nconst char
数组”,其中n是下面定义的string的大小,并具有静态存储持续时间(3.7)。
数组通俗地说是衰减指针。
4.2节
1
“NT
数组”或“T
的未知数组”的左值或右值可以转换为types“指向T
指针”的值。 结果是一个指向数组的第一个元素的指针。
由于您的string文字都包含一个字符,它们是相同的types( char[2]
,包括空字符)。
因此,以下段落适用:
§5.9
2
[…]可以比较指向同一types(指针转换后)的对象或函数的指针,结果定义如下:
[…]
– 如果相同types的两个指针
p
和q
指向不是同一对象或同一数组元素或不同对象的不同对象,或者只有其中一个为null,则p<q
,p>q
,p<=q
和p>=q
是未指定的。
未指定意味着行为取决于实现。 我们可以看到GCC给出了一个警告:
warning: comparison with string literal results in unspecified behaviour [-Waddress] std::cout << ("Z" < "A");
行为可能会在编译器或编译器设置中发生变化,但在实践中会发生什么,请参阅Wintermute的答案 。
您正在比较内存地址。 下面的例子解释了如何比较2个string:
#include "stdafx.h" #include <iostream> #include <cstring> //prototype for strcmp() int _tmain(int argc, _TCHAR* argv[]) { using namespace std; cout << strcmp("A", "Z"); // will print -1 cout << strcmp("Z", "A"); // will print 1 return 0; }
C ++中的string常量(“A”和“Z”)由C概念 – 最后一个字符为'\ 0'的字符数组表示。 这些常量必须与strcmp()types的函数进行比较。
如果你想使用C ++的std :: string比较,你必须明确说明:
cout << (std::string( "A") < "Z");
一个string表示一个指向内存区域的指针。 所以你首先比较只有内存地址与这样的代码
"Z"< "A"
比较string是用函数完成的。 他们取决于你有什么样的string。 你有字符数组的string,但他们中间也是对象。 这些对象还有其他的比较function。 例如,MFC中的CString具有Compare,但也有CompareNoCase函数。
对于你的string你最好使用strcmp。 如果你进行debugging并进入你看看该函数做了什么:它比较两个string的每个字符,如果第一个差异发生,则返回一个整数,如果相同则返回零。
int result = strcmp("Z", "A");
在这里你可以find更多的示例代码