字符串文字的C ++比较

时间:2014-12-12 18:41:04

标签: c++ string-literals

我是c ++新手(只是oldschool c)。我的儿子请求帮助,我无法解释。如果他问我“我如何比较字符串”我会告诉他使用strcmp(),但这并不是让我感到困惑的原因。以下是他的问题:

int main() 
{ 
  cout << ("A"< "Z");
}

将打印1

int main() 
{ 
  cout << ("Z"< "A");
}

也会打印1,但

int main() 
{ 
  cout << ("Z"< "A");
  cout << ("A"< "Z");
}

然后将打印10.单独两个cout语句打印1,但连续执行我得到一个不同的答案?

8 个答案:

答案 0 :(得分:86)

您正在比较内存地址。显然你的编译器会按照它遇到的顺序将字符串文字放在内存中,所以第一个字符串比第二个文件“小”。

因为在第一个片段中它首先看到“A”而第二个看到“Z”,所以“A”较小。由于它在第二个中首先看到“Z”,所以“Z”较小。在最后一个片段中,当第二个命令滚动时,它已经放置了文字“A”和“Z”。

答案 1 :(得分:20)

字符串文字具有静态存储持续时间。在所有这些比较中,比较了编译器为字符串文字分配的内存地址。似乎编译器遇到的第一个字符串文字存储在内存中,与下一个遇到的字符串文字相比,地址较低。

因此在这个程序中

int main() 
{ 
  cout << ("Z"< "A");
  cout << ("A"< "Z");
}

string literal&#34; Z&#34;地址低于字符串文字&#34; A&#34;因为它是由编译器首先发现的。

考虑到比较

  cout << ("A"< "A");

可以根据编译器的选项给出不同的结果,因为编译器可以为字符串文字分配两个内存范围,或者只使用相同字符串文字的一个副本。

来自C ++标准(2.14.5字符串文字)

  

12是否所有字符串文字都是不同的(即存储在   非重叠对象)是实现定义的。的效果   尝试修改字符串文字是未定义的。

同样适用于C.

答案 2 :(得分:13)

声明中:

cout << ("A"< "Z");

您已创建2个string literals"A""Z"。它们是const char *类型,它是指向空终止字符数组的指针。这里的比较是比较指针而不是它们指向的值。这是内存地址的比较,这是给你编译器警告的原因。比较的结果将取决于编译器从编译器到编译器分配内存的位置。在这种情况下,看起来第一个文字被编译器分配了第一个内存地址。

就像在C中正确比较这些字符串文字一样,你需要使用strcmp进行价值比较。

然而,当你做一些更惯用的c ++方式:

cout << (std::string("A") < std::string("Z"));

然后,您可以正确比较值,因为std::string定义了比较运算符。

答案 3 :(得分:7)

如果要比较实际的C ++字符串,则需要声明C ++字符串:

int main() 
{
  const std::string a("A");
  const std::string z("Z");

  cout << (z < a) << endl; // false
  cout << (a < z) << endl; // true
}

答案 4 :(得分:7)

在C ++中,结果未指定。我将使用N3337用于C ++ 11。

首先,我们必须查看字符串文字的类型。

§2.14.5

  

9普通的字符串文字和UTF-8字符串文字也是   称为窄字符串文字。一个狭窄的字符串文字   输入“ n const char数组”,其中 n 是字符串的大小   如下定义,并具有静态存储持续时间(3.7)。

通俗地说,数组衰减指针。

§4.2

  

1N T数组”或“未知数组”的左值或右值   T“的边界可以转换为”指向T的指针“的prvalue。   结果是指向数组的第一个元素的指针。

由于您的字符串文字都包含一个字符,因此它们是相同的类型(char[2],包括空字符。)

因此以下段落适用:

§5.9

  

2 [...]

     

指向相同类型的对象或函数的指针(在指针之后)   转换)可以进行比较,结果定义如下:

     
    

[...]

         

- 如果同一类型的两个指针pq指向不同     不属于同一对象或元素的对象     相同的数组或不同的函数,或者只有其中一个为null,     p<qp>qp<=qp>=q的结果未指定。

  

未指定意味着行为取决于实现。我们可以看到GCC对此发出了警告:

warning: comparison with string literal results in unspecified behaviour [-Waddress]
     std::cout << ("Z" < "A");

行为可能在编译器或编译器设置中发生变化,但在实践中会发生变化,请参阅Wintermute的answer

答案 5 :(得分:0)

您正在比较内存地址。以下示例说明如何比较2个字符串:

#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;
}

答案 6 :(得分:0)

C ++中的字符串常量(“A”和“Z”)由C概念表示 - 最后一个字符为'\ 0'的字符数组。必须将这些常量与strcmp()类型的函数进行比较。

如果您想使用C ++ std :: string比较,您必须明确说明它:

cout << (std::string( "A") < "Z");

答案 7 :(得分:0)

String表示指向内存区域的指针。所以你首先只用这样的代码比较内存地址

"Z"< "A"

比较字符串是通过函数完成的。它们取决于你拥有的“什么样的字符串”。你有char数组字符串,但它们也是对象。这些对象具有其他比较功能。例如,MFC中的CString具有Compare,还有CompareNoCase函数。

对于你的字符串,你最好使用strcmp。如果你调试并介入,你会看到函数的作用:它比较两个字符串的每个字符,如果出现第一个差异则返回一个整数,如果相同则返回零。

int result = strcmp("Z", "A");

在这里您可以找到更多sample code