跟我学C++中级篇——字面量和字符串

218 篇文章 28 订阅

一、字面量

1、字面量
字面量可能越来越直白的走进了C++开者的代码中,那么什么是字面量呢?“Literals are the tokens of a C++ program that represent constant values embedded in the source code.”,其实非常好理解,可以简单理解为常见的变量初始化(当然还是有一些细节的不同)。特别是在c++11后,允许类变量成员在声明时即初始化,这种往往是字面量。而字面量通常需要和代码一起或存储在寄存器中。
在古老的时代,字面量这个词为什么不彰显?主要是它支持的类型太少,一般只有整形和字符型、字符串型。这样,一般就把它和定义声明混在了一起,没有专门讲的必要,即使有人把这个事儿拿出来当个事儿,大家也不会引起什么重视。可从c++11以后,编程的一些基础规则改变太大,特别是后续的标准不断的在此基础上进行推进,所以,字面量才可以成为了一个专门的小知识点。
基本上现在看,常见的类型都有了字面量:
1)、布尔型、整形、字符串(const char[] or const wchar_t[])和字符类型(char、wchar_t)
2)、指针(nullptr)(C++11)
3)、char16_t和 char32_t(Unicode字符)(c++11)
4)、浮点类型(float double long double)(c++23)
5)、size_t(zu)(c++23)
6)、用户可以自定义字面量(c++11)
2、数字字面量分割符
在会计的报表里,或者看过类似的一些文章里,用某种符号对一些数字按规律进行标示,这个就是分割符,其实就是一种让人看起来比较方便的手段。字面量分割符也是如此,它使用了“'”(单个单引号),来分割数字,让它看起来更容易理解和分析,比如:

int b = 0b1110'1011'1101'1101;

一般来说,在很长的数字或者说二进制中意义更大些。它的使用有一些前提:
1)不可以在形状不和结尾
2)不可以在位数标志(如0x,0,0b)之后
3)不可在小数点旁
4)不可连续使用
5)不可在指数表示法中使用

二、字符串和字面量

在字符串中,其实对字面的量的理解方式与其它类型是一样的。但是,字符串有一个特殊的问题,那就是里面会有一些特殊字符,比如“/”、“'”等等。这时候儿一般来说在早期使用转义字符来处理。这种转义字符处理字符串,可以在很多的代码中看到,包括开源的一些有名的框架中。这种处理方式的缺点是,不容易理解,特别是在一些字符串的拼接中,往往让新手蒙圈。那么在c++11后提供了一个简单的操作方式:

int main()
{
  std::string sss = R"json(123455)json";
  std::cout<<sss<<std::endl;
  sss = R"test(abcd\/;")test";
  std::cout<<sss<<std::endl;
  return 0;
}

这种方式的优点在于它可以保留原汁原味儿的字符串而不用使用转义字符。特别是,它可以在字符串前增加一些标注,让字符串看起来更容易被阅读着理解,比如上面的json,这个是不被标记到字符串的。
那如果需要增加引号呢,在前面也提到过:

int main() {
    string str = "my test";
    std::cout << str << std::endl;
    std::cout << std::quoted(str) << std::endl;
    return 0;
}

另外在c++11标准中,还对除s字符的d字符和r字符也有类似的处理,但一般应用就比较少了,有兴趣可以查一下。
简单说明一下各种字符定义:

1)s字符序列 - 一个或多个s字符
s字符 - 下列之一:
一个基本s字符
一个转义序列,定义见转义序列
一个通用字符名,定义见转义序列
2)基本s字符 - 翻译字符集中的字符,不包括双引号(“)、反斜杠(\)和换行符
3)d字符序列 - 一个或多个d字符,最多十六个
4)d字符 - 基本字符集中的字符,不包括括号、反斜杠和空格
5)r字符序列 - 一个或多个r字符,不得包含闭序列 )d字符序列”
6)r字符 - 翻译字符集中的字符
说白话,开发者常见的字符串操作就是s字符序列,扣除一些指定字符后就变成d和r序列。

三、例程

下面看一个综合的例程:

#include <iostream>
void testLiterals()
{
    int i = 42;
    int o = 052;
    int x = 0x2a;
    int X = 0X2A;
    int b = 0b101010; // C++14
    int bb = 0b0001'0011'1010;//c++14
    double db = 3.14'159'265'789;//c++14

    unsigned long long l1 = 19426344073709350598ull;       // C++11
    unsigned long long l2 = 18'446'744'073'709'550'582llu; // C++14
    unsigned long long l3 = 1874'6714'0939'0975'0291uLL;   // C++14
    unsigned long long l4 = 186967'331737'0'95505'99LLU;   // C++14

    size_t st = 10zu;   //C++23以下编译出错
    float f = 1123.456f; // C++23 浮点数字面量,后缀 f
    double d = 1123.456;  // C++23 浮点数字面量,没有后缀,默认为 double
    long double ld = 1273.856L; // C++23 长双精度浮点数字面量,后缀 L

    // 字符表示
    char16_t u16char = u'C'; // Unicode 字符 'C'
    char32_t u32char = U'中'; // Unicode 字符 '中'

    // 字符串字面量
    const char16_t* u16str = u"test"; // char16_t 字符串字面量
    const char32_t* u32str = U"中国"; // char32_t 字符串字面量
}
int main()
{
   testLiterals();
   return 0;
}

代码很简单,没啥可说的,这都是标准定义,只要照着做就好。

四、总结

其实从本文的分析就可以看出,标准的进步对编程还是非常有好处的。至少,可以减轻编译的复杂度。特别是在一些看起来不太起眼的地方,更是让开发者省心。所以,还是要与时俱进,拥抱变化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值