为什么在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)。
事情变成这样的原因是历史性的。