【现代C++】自定义字面量-序:字面量(一)

(点击上方公众号,可快速关注)

C++11引入了自定义字面量,由于这个语言特性的外延较大,为了系统介绍它,先把字面量的知识补全。在看语言规范的过程中,的确发现了好多知识点是以前没接触过的,这些没接触过的知识点主要来源两方面:

  • C++11后修复。现代C++在越来越多的方面修复早期C++不合理的地,甚至C语言的一些不合理的规则,比如,本篇文章要介绍的整数字面量的整数提升规则。

  • C++11后新增。增加了一些方便的语言特性,用于提升代码可读和生产力。比如,二进制整数字面量、数字分隔符等。

为了保持文章的轻量级,本篇主要介绍字面量的概念和整数字面量、浮点字面量的内容。

何为字面量

简单来说,字面量就是从字面上看,它的值等于其自身的常量。在C语言中,通常称之为常量,而在C++中,常量包含的内容要多于C,所以被称之为字面量。

注意上面标黑的文字,这是字面量最重要的特征,基本上所有的语言都遵循这个原则。由于C++没有提供REPL(Read-Eval-Print-Loop),我们这里拿Python举例:

>>> 1
1

>>> 'abc'
'abc'

>>> 1.0
1.0

在Python中,字面量有整数、浮点数和字符串等几类,可以看到,对字面量求值之后,结果的值就是字面量本身,在C++中同样如此。

字面量的种类

在C++中,字面量包括7类。

整数字面量(integer literal)
前缀

前缀标识进制信息,没有前缀代表默认的10进制。

42;     //10进制,无前缀
052;    //8进制,前缀0
0x2a;   //16进制,前缀0x
0X2A;   //16进制,也可前缀0X
0b101010;//2进制,前缀0b
0B101010;//2进制,也可前缀0B

特别说明,

  • 二进制的字面量是C++14引入的,在某些应用场景下非常有用,如,位运算。

  • 0x0X都可以接大写和小写的字母;只是通常0x后接小写字母,0X接大写字母。

  • 如果数字太长,为便于阅读,可使用数字分隔符【C++14引入】将字面量分隔开,各种进制的表示都可以使用;分隔的位置可以灵活指定,符合自己的阅读习惯即可:

    18'446'744'073'709'550lu
    
后缀

后缀信息也是可选的,所有的情况在下表中进行了总结。下面的表信息量比较多,需要关注的几点有:

  • 后缀不能唯一决定字面量的数据类型,这是最容易出现的错误。没有后缀的情况,很多人认为字面量的类型就是int,这是不准确的,这取决于它的大小,它的类型是相应表格单元里从上到下第一个能表示它的类型。但每种情况的第一个类型是跟后缀对应的。

  • 十进制和其他进制(2、8、16)不同,不包含uU的情况,其他进制多了相应的无符号版本。

  • C++11开始支持long long int类型及其后缀,虽然在此之前很多编译器已经支持。

  • 注意表格里唯一的until C++11,使得各类型行为统一,更容易记忆了。

  • 编译器会尽可能地将字面量字面量表示出来,如果列表里的类型表示不了,编译器可能会使用扩展的整型类型(extended integer type)表示,如果还不能表示出来,则报错。扩展的整数类型属于编译器的扩展,每个编译器有所不同,所以一般不要依赖这种行为。

后缀 十进制 二进制, 八进制, 十六进制
no suffix int
long int
long long int(since C++11)
int
unsigned int
long int
unsigned long int
long long int(since C++11)
unsigned long long int(since C++11)
u or U unsigned int
unsigned long int
unsigned long long int(since C++11).
unsigned int
unsigned long int
unsigned long long int(since C++11)
l or L long int
unsigned long int(until C++11)
long long int(since C++11).
long int
unsigned long int
long long int(since C++11)
unsigned long long int(since C++11)
both
l/L
and
u/U
unsigned long int
unsigned long long int(since C++11).
unsigned long int(since C++11)
unsigned long long int(since C++11)
ll or LL long long int(since C++11) long long int(since C++11)
unsigned long long int(since C++11)
both
ll/LL
and
u/U
unsigned long long int(since C++11) unsigned long long int(since C++11)
浮点字面量(floating-point literal)

浮点字面量也有后缀,要比整数字面量简单地多,只有两组,见下表:

后缀 类型
no suffix double
f or F float
l or L long double

可以看到,后缀对应的第二列单元格内的类型只有一个,这是跟整型字面量不同:

  • 浮点字面量的类型由其后缀决定,而整型字面量的类型实际上只是部分由后缀决定,它有一个提升的过程。

  • 浮点字面量的值如果不能被相应的类型表示,则报错

跟整型字面量相同,C++14引入的数字分隔符也可应用在浮点字面量中。

下面给出一些常见形式的字符串字面量例子:

1e5, 1e-5  // 指数可正可负   
1., 1.e-5  // 若为0,小数部分可省略
0.1 == .1  // 若为0,整数部分可省略
. // 错误,整数和小数部分不能同时省略
0.1, 0.1F, 0.1L // 不同后缀
1e5 == 1E5    // E和e不影响值
十六进制浮点字面量

上面介绍的浮点字面量基于十进制,我们平常接触到的基本上都是这一类。C++17引入了十六进制的浮点字面量,我们做下跟十进制浮点字面量的语法比较:

比较项 十进制浮点字面量 十六进制浮点字面量
前缀 0x0X
指数 Ee后接十进制的小数 pP后接二进制的小数

在某些情况下,使用二进制或十六进制能方便浮点数的表示,这是引入十六进制形式的主要目的。下面给出几例:

0.25 == 0x1.p-2       // 1.0 * 2^-2
49.625 == 0xC.68p+2   // 0xC.68p * 2^2

喜欢我的文章,请关注我的公众号。转载请标明出处。

【现代C++】自定义字面量-序:字面量(一)_第1张图片

你可能感兴趣的:(java,编程语言,twitter,gwt,isp)