type
status
date
slug
summary
tags
category
icon
password
Property
基本内置类型
C++
定义了一套包括算术类型和空类型在内的基本数据类型- 算术类型包含了字符、整型数、布尔值和浮点数
- 空类型不对应具体的值,仅用于一些特殊的场合,例如函数的返回类型为空类型、函数的参数为空、指针指向
void
算术类型又分为两类: 整型(包括字符符和布尔类型在内)和浮点型
bool
类型的取值是true
或false
一个
char
的大小和一个机器字节一样,确保可以存放机器基本字符集中任意字符对应的数字值。wchar_t
确保可以存放机器最大扩展字符集中的任意一个字符。类型char16_t
和char32_t
则为Unicode字符集服务在整型类型大小方面,
C++
规定short
≤ int
≤ long
≤ long long
浮点型可表示单精度、双精度和扩展精度值,分别对应
float
、double
和long double
类型:- 单精度有1位符号,8位指数,23位小数,10进制下有6位有效数字:
- 双精度有1位符号,11位指数,52位小数,10进制下有10位有效数字:
带符号类型和无符号类型
除去布尔型和扩展字符型,其他整型可以分为带符号(signed)和无符号(unsigned)两种。带符号类型可以表示正数、负数和0;无符号类型只能表示大于等于0的数值。
类型
int
、short
、long
和long long
都是带符号的,在类型名前面添加unsigned
可以得到对应的无符号类型,如unsigned int
。与其他整型不同,字符型分为
char
、signed char
和unsigned char
三种,但是表现形式只有带符号和无符号两种。类型char
和signed char
并不一样, char
实际上会表现为上述两种形式中的一种,具体是哪种由编译器决定。如何选择算数类型
- 当明确知晓数值不可能为负时,应该使用无符号类型
- 使用
int
执行整数运算,如果数值超过了int
的表示范围,应该使用long long
类型
- 在算数表达式中不要使用
char
和bool
类型,只有在存放字符或布尔值时才使用它们。因为char
在一些机器上是有符号的, 而在另一些机器上又是无符号的,所以使用char
进行运算特别容易出问题。如果需要使用一个不大的整数,应该明确指定它的类型是signed char
还是unsigned char
。
- 执行浮点数运算时建议使用
double
类型。
float
通常精度不够,而且双精度浮点数和单精度浮点数的计算代价相差无几。对于某些机器, 双精度运算甚至比单精度还快。long double
提供的精度在一般情况下是没有必要的,况且它带来的运行时消耗也不容忽视。自动类型转换
当在程序的某处使用了一种类型而其实对象应该取另一种类型时, 程序会自动进行类型转换。进行类型转换时,类型所能表示的值的范围决定了转换的过程。
- 把非布尔类型的算术值赋给布尔类型时,初始值为0则结果为
false
,否则结果为true
;把布尔值赋给非布尔类型时,初始值为false
则结果为0,初始值为true
则结果为1
- 把浮点数赋给整数类型时,进行近似处理,结果值仅保留浮点数中的整数部分;把整数值赋给浮点类型时,小数部分记为0,如果该整数所占的空间超过了浮点类型的容量,精度可能有损失。
- 赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数(8比特大小的
unsigned char
能表示的数值总数是256)取模后的余数;赋给带符号类型一个超出它表示范围的值时,结果是未定义的, 程序可能继续工作,可能崩溃,也可能生成垃圾数据。
不要混用带符号类型和无符号类型
我们不会故意给无符号对象赋一个负值, 却可能写出这么做的代码。例如,当一个算术表达式中既有无符号数又有
int
值时, 那个int
值会转换成无符号数:当从无符号数中减去一个值时, 不管这个值是不是无符号数,都必须确保结果不能是一个负值。
无符号数不会小于0这一事实关系到循环的写法,用无符号数可能陷入死循环:
一种解决的办法是, 用
while
语句来代替for
语句, 因为前者能够在输出变量之前( 而非之后)先减去1 :字面值常量
一个形如42的值被称作字面值常量, 这样的值一望而知。每个字面值常量都对应一种数据类型,字面值常量的形式和值决定了它的数据类型。
整型和浮点型字面值
可以将整型字面值写作十进制数、八进制数或十六进制数的形式:
整型字面值的具体数据类型由它的值和符号决定。默认情况下十进制字面值是带符号数,类型是
int,long,long long
中能容纳当前值的尺寸最小的那个。八进制和十六进制字面值既可能是带符号的也可能是无符号的。尽贵整型字面值可以存储在带符号数据类型中, 但严格来说,十进制字面值不会是负数,负号并不在字面值之内, 它的作用仅仅是对字面值取负值而已。
可以通过在常量后添加后缀来声明字面值常量的类型,后缀u或U表示为
unsigned
,后缀l或者L表示为long
类型,后缀ll或者LL表示为long long
类型,可以通过组合ul将常量声明为unsigned long
型:默认情况下,浮点数字面值是一个
double
类型,表现为一个小数和科学计数法表示的指数,其中指数部分用E或e标识。可以通过在常量后添加后缀来声明浮点数字面值常量的类型,添加后缀f或F表示为float
,添加后缀l或者L表示为long double
类型:字符和字符串字面值
单引号括起来的一个字符是
char
型字面值,双引号括起来的零个或多个字符则构成字符串型字面值:字符串字面值的类型实际上是字符数组,编译器会向每个字符串结尾添加一个空字符('\0'),因此字符串字面值的实际长度要比它的内容多1。例如,字面值
'A'
表示的就是单独的字符A,而字符串"A"
则代表了一个字符的数组,该数组包含两个字符:字母A和一个空字符。如果两个字符串字面值紧邻且仅由空格、缩进和换行符分隔,则它们实际上是一个整体。
转义序列
有两类字符程序员不能直接使用:
- 一类是不可打印( nonPrintable ) 的字符, 如退格或其他控制字符, 因为它们没有可视的图符
- 另一类是在
C++
语言中有特殊含义的字符( 单引号、双引号、问号)
在这些情况下需要用到转义序列,转义序列均以反斜线作为开始,
C++
定义的转义序列包括:在程序中,上述转义序列被当作一个字符使用。
也可以使用泛化的转移序列,形式是\后跟 1~3 个八进制数字或 \x 后跟 1 个或多个十六进制数字。
布尔字面值和指针字面值
指定字面值的类型
通过给字面值增加前缀和后缀来改变字面值的默认类型: