C++字符串文本的比较
C++ Comparison of String Literals
我是一个 c++ 新手(只是老派的 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,但连续执行我得到不同的答案?
您正在比较内存地址。显然,您的编译器按照遇到字符串文字的顺序将字符串文本放在内存中,因此第一个"小于"第二个。
由于在第一个片段中,它首先看到"A",其次看到"Z",因此"A"较小。由于它在第二个中看到"Z",因此"Z"较小。在最后一个代码片段中,当第二个命令滚动时,它已经放置了文字"A"和"Z"。
字符串文本具有静态存储持续时间。在所有这些比较中,都有编译器为字符串文字分配的内存的比较地址。似乎编译器遇到的第一个字符串文本存储在内存中,与下一个遇到的字符串文本相比,地址较低。
因此在这个程序中
int main()
{
cout << ("Z"< "A");
cout << ("A"< "Z");
}
字符串文字"Z"的地址都低于字符串文字"A",因为它首先由编译器找到。
考虑到这种比较
cout << ("A"< "A");
可以根据编译器的选项给出不同的结果,因为编译器可以为字符串文本分配两个内存范围,或者只使用相同的字符串文本的一个副本。
来自C++标准(2.14.5 字符串文本(
12 是否所有字符串文本都是不同的(即存储在 非重叠对象(是实现定义的。的效果 尝试修改字符串文本是未定义的。
这同样适用于 C。
在语句中:
cout << ("A"< "Z");
您已经创建了 2 个字符串文本:"A"
和 "Z"
。这些类型为 const char *
,它是指向以 null 结尾的字符数组的指针。这里的比较是比较指针,而不是它们指向的值。正是这种内存地址的比较为您提供了编译器警告。比较的结果将取决于编译器分配内存的位置,从编译器到编译器,内存到哪个位置将有些任意。在这种情况下,看起来找到的第一个文本被编译器分配了第一个内存地址。
就像在 C 中要正确比较这些字符串文字一样,您需要使用 strcmp
这将进行值比较。
但是,当您通过执行以下操作以更惯用的c ++方式执行某些操作时:
cout << (std::string("A") < std::string("Z"));
然后,您将获得值的正确比较,因为该比较运算符是为std::string
定义的。
如果要比较实际的字符串C++,则需要声明C++字符串:
int main()
{
const std::string a("A");
const std::string z("Z");
cout << (z < a) << endl; // false
cout << (a < z) << endl; // true
}
在C++中,结果未指定。我将在 3337 年使用 N11 C++。
首先,我们必须查看字符串文字的类型是什么。
§2.14.5
9
普通字符串文字和 UTF-8 字符串文字也是 称为窄字符串文本。窄字符串文本具有 键入">Nconst char
数组",其中 n 是字符串的大小 定义如下,并具有静态存储持续时间 (3.7(。
数组通俗地说是衰减到指针。
§4.2
1
"N T
数组"或"未知数组"类型的左值或右值T
的界限"可以转换为"指向T
的指针"类型的 prvalue 。 结果是指向数组的第一个元素的指针。
由于字符串文本都包含一个字符,因此它们是相同的类型(char[2]
,包括空字符。
因此,以下段落适用:
§5.9
2
[...]指向相同类型的对象或函数的指针(在指针之后( 转换(可以进行比较,结果定义如下:
[...]
— 如果两个指针
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 个字符串:
#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++ 中的字符串常量("A"和"Z"(由 C 概念表示 - 最后一个字符为"\0"的字符数组。 这样的常量必须与 strcmp(( 类型的函数进行比较。
如果你想使用C++ std::string 比较,你必须明确声明它:
cout << (std::string( "A") < "Z");
字符串表示指向内存区域的指针。所以你首先只比较内存地址和这样的代码
"Z"< "A"
比较字符串是通过函数完成的。它们取决于您拥有"什么样的字符串"。你有 char 数组字符串,但它们也是对象。这些对象具有其他比较功能。例如,MFC 中的 CString 具有 Compare 和 CompareNoCase 函数。
对于您的字符串,您最好使用 strcmp。如果你调试并单步执行,你会看到函数的作用:它比较两个字符串的每个字符,如果出现第一个差异,则返回一个整数,如果相同,则返回零。
int result = strcmp("Z", "A");
在这里,您可以找到一些进一步的示例代码
- 比较文本文件的元素
- 比较文本文件的元素
- 如何在 c++ 中比较两个文本文件
- C++:比较运算符>和字符串文本的意外结果
- 读取 MIFARE 卡块并将其部分块与一些文本进行比较
- C++比较两个文本文件的上下文
- 逐行读取文本文件并计数比较运算符
- C 比较文本文件和分段故障(核心倾倒)
- 比较从文本文件中读取的并行阵列
- 将 char * 与字符串文本进行比较时出现问题
- 与字符串文本进行比较会导致未指定的行为
- 使用比较运算符和字符串比较函数读取文本文件的子部分时出现问题
- 正在检查用户的有效输入并与文本文件进行比较
- C++:警告:与字符串文本进行比较会导致未指定的行为 [-Waddress]
- C++比较两个字符串文本
- C++字符串文本的比较
- 如何将文本文件中的行与以下的多行进行比较
- 正在比较文本文件中的字符串
- 如何比较两个不同文本文件中的两个不同字符串
- 使用指针比较文本的字符与单个字符