为什么在 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'
,和'\0'
。(最后一个字符称为终止空值)。
该值'4'
是一个char
文字(假设您的编译器使用 ASCII 或兼容字符集,标准不保证)具有52
.
该表达式"hello" + '4'
随后被编译器视为"hello" + (char)52
. Achar
是整数类型,因此最终结果"hello" + '4'
是指向字符串文字的第 53 个字符的指针(不存在,因为字符串文字"hello"
表示为包含六个元素的数组)。
所以结果"hello" + 4
是一个指向不存在字符的指针。
s
in的初始化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';
它的工作方式基本相同(s
in"hello"s
形成类型的文字std::string
而不是表示为 的数组char
,因此加法的结果也是 a std::string
)。
事情变成这样的原因是历史性的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句