特殊情况
#include <iostream>
#include <stdlib.h>
#include <string>
int main()
{
//(const char [7])"Cherno",7字节,因为末尾有一个空字符'\0'
"Cherno";
std::cout << "Cher\0no" << std::endl;//Cher
const char name[8] = "Che\0rno";
std::cin.get();
}

注意事项 #
#include <iostream>
#include <stdlib.h>
#include <string>
int main()
{
//(const char [7])"Cherno",7字节,因为末尾有一个空字符'\0'
"Cherno";
std::cout << "Cher\0no" << std::endl;//Cher
const char name[8] = "Che\0rno";
std::cout << strlen(name) << std::endl;//3,不把\0算在内
/* 错误的,某些编译器允许编译通过,但没效果
char* name1 = "Cherno";
name1[2] = 'a';
std::cout << name1 << std::endl;//Cherno
*/
//一定要修改的话
char name2[] = "Cherno";
name2[2] = 'a';
std::cout << name2 << std::endl;//Charno
std::cin.get();
}
不同类型的字符串 #
#include <iostream>
int main()
{
const char* name = "Cherno";
const char* name_ = u8"Cherno";
//字符串中的每个字符都是宽字符(wchar_t 类型),
//通常是16位或32位,取决于系统(大小平台相关)
//L 前缀表示这是一个宽字符字符串
const wchar_t* name2 = L"Cherno";
// C++11后的UTF-16字符串,固定每个字符2字节
const char16_t* name3 = u"Cherno";
// C++11后的UTF-32字符串,固定每个字符4字节
const char32_t* name4 = U"Cherno";
std::cin.get();
}
字面量运算符 #
//"" 是字面量运算符名称的一部分
//它表示这个运算符处理的是字符串字面量
//其他类型的字面量有不同的前缀:
// 不同的字面量类型有不同的运算符名称:
std::string operator""s(...); // 字符串字面量
long double operator""ld(...); // 浮点数字面量
unsigned long long operator""ull(...); // 整数型字面量
#include <iostream>
#include <string>
#include <stdlib.h>
int main()
{
//启用了 "text"s 语法,让创建 std::string 对象更加
// 直观、类型安全,特别是在自动类型推导和复杂字符串场景下非常有用。
using namespace std::string_literals;
//报错
//std::string name0 = "Cherno" + " hello";
std::string name0 = std::string("Cherno") + " hello";
//// 普通运算符重载:没有引号
//std::string operator+(const std::string & a, const std::string & b);
// 字面量运算符:必须有 ""
//std::string operator""s(const char* str, size_t len);
//std::string operator""s(const char* str, size_t len);
//下面的语句,相当于std::string name1 = operator""s("Cherno", 6) + " hello";
std::string name1 = "Cherno"s + " hello";
std::cout << name1 << std::endl;
std::string name2 = u8"Cherno"s + " hello";
std::wstring name3 = L"Cherno"s + L" hello";
std::u32string name4 = U"Cherno"s + U" hello";
//R 表示 Raw string literal(原始字符串字面量),括号内的内容会完全按照原样被存储,包括换行符、制表符等特殊字符。
const char* example = R"(Line1
Line2
Line3
Line4)";
/*
Line1
Line2
Line3
Line4
*/
std::cout << example << std::endl;
const char* example1 = "Line1\n"
"Line2\n"
"Line3\n"
"Line4";
std::cout << example1 << std::endl;
std::cin.get();
}
查看字面量汇编文件 #
#include <iostream>
int main()
{
char name[] = "Cherno";
name[2] = 'a';
std::cout << name << std::endl;
std::cin.get();
}

解释:先从只读数据段复制字符串常量到栈变量,然后进行修改。
; 5 : char name[] = "Cherno";
mov eax, DWORD PTR ??_C@_06MDBPMDDK@Cherno@
; 6 : name[2] = 'a';
; 7 : std::cout << name << std::endl;
lea rdx, QWORD PTR name$[rsp]
mov rcx, QWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
mov DWORD PTR name$[rsp], eax
movzx eax, WORD PTR ??_C@_06MDBPMDDK@Cherno@+4
mov WORD PTR name$[rsp+4], ax
movzx eax, BYTE PTR ??_C@_06MDBPMDDK@Cherno@+6
mov BYTE PTR name$[rsp+6], al
mov BYTE PTR name$[rsp+2], 97 ; 00000061H
- 初始字符串常量在只读内存:
??_C@_06MDBPMDDK@Cherno@:
偏移0: 'C' 'h' 'e' 'r' (4字节 = DWORD)
偏移4: 'n' 'o' (2字节 = WORD)
偏移6: '\0' (1字节 = BYTE)
- 复制到栈上(name$[rsp]位置):
[rsp+0] = 'C' (name[0])
[rsp+1] = 'h' (name[1])
[rsp+2] = 'e' (name[2]) <-- 将被修改
[rsp+3] = 'r' (name[3])
[rsp+4] = 'n' (name[4])
[rsp+5] = 'o' (name[5])
[rsp+6] = '\0' (name[6])
- 修改后:
[rsp+2] = 'a' (97 = 0x61)
最终字符串变为"Charno"