为什么在C++中将字符串和char连接起来会返回一个空字符串?

为什么在 C++ 中连接字符串和字符会返回一个空字符串?

#include <iostream>
#include <string>
#include <assert.h>

int main() {
    std::string s = "hello" + '4';
    assert(s == ""); // why does s equal "" here?
}

回答

问题出在

std::string s = "hello" + '4';

它不会做任何类似于将 a 附加'4'到字符串的远程操作。实际行为与您的期望完全不同。

字符串文字"hello"表示为6的阵列const char,其值'h''e''l''l''o',和''。(最后一个字符称为终止空值)。

该值'4'是一个char文字(假设您的编译器使用 ASCII 或兼容字符集,标准不保证)具有52.

该表达式"hello" + '4'随后被编译器视为"hello" + (char)52. Achar是整数类型,因此最终结果"hello" + '4'是指向字符串文字的第 53 个字符的指针(不存在,因为字符串文字"hello"表示为包含六个元素的数组)。

所以结果"hello" + 4是一个指向不存在字符的指针。

sin的初始化std::string s = "hello" + '4';然后将该指针传递给 的构造函数std::string。该构造函数错误地假设它传递了空终止字符串的第一个字符的地址。这不是传递的内容,因此结果是未定义的行为。

该断言assert(s == "")实际上并不能保证为真。对于您的编译器和您的主机系统来说,这恰好是真的。但是,由于发生了未定义的行为,任何结果都是可能的(理论上包括在初始化过程中重新安装操作系统s,并且永远不会到达assert())。

要按照您的意图进行操作,您需要强制编译器使用std::string右侧的对象(而不是指针算法)。这样做的一种选择是

 std::string s = std::string("hello") + '4';

这是通过std::string从文字构造 a来工作的"hello"std:string支持operator+()可用于将 a 连接char到 a 的an std::string(并返回std::string用于初始化的 a s)。

以上适用于所有 C++ 标准(自 1998 年以来)。第二种选择(自 C++14 起)是使用文字表示法

std::string s = "hello"s + '4';

它的工作方式基本相同(sin"hello"s形成类型的文字std::string而不是表示为 的数组char,因此加法的结果也是 a std::string)。

事情变成这样的原因是历史性的。


以上是为什么在C++中将字符串和char连接起来会返回一个空字符串?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>