字符串字面量

字符串字面量

cout <<"hello"<< endl;

在上面代码中“hello"是一个字符串常量,因为这个字符串以值的方式给出,而不是一个变量。它存储在内存中的只读部分。通过这种方式,编译器可重用相同字符串字面量的引用。从而优化内存的使用。即使一个程序中使用几百次”hello“字符串字面量,编译器也旨在内存中创建一个hello实例,这种技术叫做字面量池。

字符串字面量可以赋值给变量,但是因为字符串字面量位于内存的只读部分,且使用了字面量池,所以这样做会产生风险。c++标准正式指出:字符串字面量的类型为”n个const char*的数组“,然而为了向后兼容较老的不支持const的代码,大部分编译器不会强制程序将字符串字面量赋值给const char *类型的变量。这些编译器允许将字符串字面量赋值给不带有const的char *,而且整个程序可以正常运行,除非试图修改字符串,一般情况下,修改字符串字面量的行为是未定义的。可能会导致程序崩溃,也可能继续执行,会产生一些莫名其妙的副作用;具体是否生效主要是看编译器。例如下面的未定义行为:

char *p {"hello"};
p[1] = 'a';      // undefined behavior

一种更安全的编码方式是在引用字符串常量的时候,使用指向const字符的指针。下面的代码包含同样的bug,到那时由于这段代码将字符串字面量赋值给const char *,因此编译器会捕捉到任何写入只读内存的企图。

const char* p {"hello"};
p[1] = 'a';             // ERROR!Attempts to write read-only memory

可以将字符串字面量作为字符数组的(char[])的初始值,这样,编译器会创建一个足以存下这个字符串的数组,然后将字符串复制到这个数组中,因此,编译器不会将字面量存放在只读区域,也不会进行字面量池操作。

char arr[] {"hello"};
arr[1] = 'a';     // can modified

原始字符串字面值

原始字符串字面量(raw string literal)是可横跨多行代码的字符串字面量,需要转义嵌入的双引号,像\t,\n这种转义序列不按照转义序列的方式处理,而是按照普通文本方式处理。例:

const char* str {"hello "world"!"}; // error
// 对于普通字符串必须转义双引号,如下
const char* str {"hello \"world\"!"};

对于原始字符串字面量,就不需要转义双引号了,原始字符串字面量以R“(开头,以”)结尾。

const char* str {R"(hello "world"!)"};

下面两个写法,输出的格式是相同的

const char* str {"line1 \nline2"};
const char* str {R"(line1
				 line2)"};

因为原始字符串字面量是以)“结尾,所以使用该语法时,不能在字符串中嵌入)”。例如

const char* str {R"(hello)" world)"}; // error

如果需要嵌入)",则需要使用扩展的原始字符串字面量语法, 如下:

R”d-char-sequence(r-char-sequence)d-char-sequence"

r-char-sequence是实际的原始字符串,d-char-sequence是可选的分隔符序列,原始字符串首尾的分隔符序列应该一致。分隔符最多能有16个字符,应该选择为出现在原始字符串字面量中的序列作为分隔符序列。上述事例可以改为:

const char* str {R"-(hello)" world)-"};

在操作数据库查询字符串、正则表达式和文件路径时,原始字符串字面量可以令程序的编写更加方便。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值