C++定义了一套包括算术类型和空类型在内的基本数据类型。算术类型包含字符、整型数、布尔值和浮点数。空类型不对应具体的值,最常见的是函数不返回任何值时返回空类型。
1.算术类型
算术类型分为整型和浮点型,下表是是对整型和浮点类型说明和含义,以及C++标准规定的最小尺寸。
类型 | 含义 | 最小尺寸 |
---|---|---|
bool | 布尔类型 | 未定义 |
char | 字符 | 8位 |
wchar_t | 宽字符 | 16位 |
char16_t | Unicode字符 | 16位 |
char32_t | Unicode字符 | 32位 |
short | 短整型 | 16位 |
int | 整型 | 16位 |
long | 长整型 | 32位 |
long long | 长整型 | 64位 |
float | 单精度浮点数 | 6位有效数字 |
double | 双精度浮点数 | 10位有效数字 |
long double | 扩展精度浮点数 | 10位有效数字 |
整型说明:
bool 的取值是真(true)或者假(false)
C++提供了几种字符类型:char是基本字符类型,一个char的大小和一个机器字节一样,wchar_t可以存放机器基本字符集中的任意字符,char16_t和char32_t则为Unicode字符集服务。
除去布尔类型和字符类型之外,其他整型可划分为带符号的(signed)和无符号的(unsigned)两种。带符号类型可以表示正数、负数和0,无符号类型只能表示大于等于0的值。
类型int、short、long和long long 都是带符号的,通过在类型名前加unsigned 就可以得到无符号类型。类型unsigned int可以缩写为unsigned。
与其他整型不同,字符类型被分为了char、signed char 和unsigned char三种。需要注意,和整型不同,char和signed char并不一样。尽管字符类型有三种,但是字符的表现形式却只有带符号和无符号两种,char的表现形式由编译器决定。
浮点型说明:
浮点型可以表示单精度、双精度和扩展精度。通常,float以一个字(32比特)来表示,double以2个字(64比特)来表示,long double 以3或者4个字(96或者128比特)来表示。一般来说,float和double分别为7和16个有效位,long double 常被用于特殊浮点需求的硬件,它的具体实现不同,精度也各不相同。
如何选择类型:
1.当明知晓数值不可能为负数时,选用无符号类型。
2.使用int执行整数运算。在实际使用中,short常常显得太小而long一般和int有一样的尺寸。如果你的数值超过了int,选用long long。
3.在算术表达式里不要用char和bool。因为char在一些机器上是有符号的,而另外一些机器上又是无符号的,使用char进行运行特别容易出错。如果你需要使用一个不大的整数,那么要明确指定它的类型是signed char 或者unsgined char。
4.执行浮点运算选用double。因为float通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。
2.类型转换
对象的类型定义了对象能包含的数据和能参与的运算,其中一种运算被大多数类型支持,就是将对象从一种给定的类型转换为另一种类型
含有无符号类型的表达式
尽管我们不会故意给无符号对象赋一个负数,却可能写出这样的代码。例如,当一个算术表达式中既有无符号数又有int值时,那个int值就会转化为无符号数。把int转化成无符号数的过程和把int直接赋给无符号变量一样:
unsigned u = 10;
int i = -42;
std::cout << i+i << std::endl; //输出-84
std::couyt << u+i << std::endl; //如果int占32位,输出4294967264
在第一个表达式里,两个负整数相加得到了期望的结果。在第二个表达式时,相加前先把-42转化成了无符号数,-42转成无符号相当于对-42取补码,即先求-42的反码,再加1,得到的结果再加10。
当从无符号数减去一个值时,不管这个值是不是无符号数,我们都必须确保结果不能是一个负数:
unsigned u1=42, u2=10;
std::cout << u1-u2 << std::endl; //输出32
std::couyt << u2-u1 << std::endl; //结果是-32取模后的值
//下面for循环会进入死循环,因为当u=0时,--u得到-1,由于u是unsigned类型,所以u的值是-1会被转成无符号
//如果int是32位,则--u的结果是4294967295,结果大于等于0
for(unsigend u=10; u>=0; --u)
{
std::cout << u << std::endl;
}
切勿混用带符号和无符号类型,当带符号类型取值为负时会出现异常结果,这是因为带符号类型会自动转换为无符号类型。
3.字面值常量
整型字面值
我们可以将整型字面值写作十进制、八进制和十六进制的形式。以0开头的整数表示八进制,以0x或者0X开头的整数表示十六进制。没有0、0x、0X开头的表示十进制。
20(十进制) 024(八进制) 0x14(十六进制)
默认情况下十进制字面值是带符号数,八进制和十六进制字面值即可能带符号也可能是无符号的。尽管整型字面值可以存储带符号数据类型,但是严格来说,十进制字面值不会是负数。如果我们使用了一个形如-45的负十进制字面值,那个负号并不在字面值之内,它的作用仅仅是对字面值取负值而已。
浮点型字面值
浮点型字面值表现表现为一个小数或以科学计数法表示的指数,其中指数部分用E或者e表示。
3.1415926 3.1415926E0 0. 0e0 .001
字符和字符串字面值
由单引号括起来的一个字符成为char型字面值,双引号括起来的零个或多个字符则构成字符串型字面值
'a' //字符字面值
"aaa" //字符串字面值
转义序列
有两类字符不能直接使用:一类是不可打印字符,如退格或者其他控制字符,因为他们没有可视字符;另一类是在C++语言中有特殊含义的字符(单引号,双引号,问号,反斜杠等)。这些情况需要用到转义序列,转义序列以反斜线为开始:
符号 | 含义 |
---|---|
\n | 换行符 |
\v | 纵向制表符 |
\ | 反斜线 |
\r | 回车符 |
\t | 横向制表符 |
\b | 退格符 |
? | 问号 |
\f | 进纸符 |
\a | 报警符 |
\“ | 双引号 |
\‘’ | 单引号 |
也可以使用泛化的转义序列,其形式是\x后紧跟1个或多个十六进制数字,或者\后紧跟1个、2个或者3个八进制数,其中数字部分表示的是字符对应的数值。假设使用Latin-1字符集,一下是一些实例:
符号 | 含义 |
---|---|
\7 | 响铃 |
\0 | 空字符 |
\12 | 换行符 |
\115 | 字符M |
\40 | 空格 |
\x4d | 字符M |
注意如果反斜线\后面跟着的八进制数字超过3个,只有前面3个数字与\构成转义序列。相反,\x要用到后面跟着的所有数字。
指定字面值类型
通过添加下表所列的前缀或者后缀,可以改变整型、浮点型和字符型字面值的默认类型
字符和字符串字面值
前缀 | 含义 | 类型 |
---|---|---|
u | Unicode 16字符 | char16_t |
U | Unicode 32字符 | char32_t |
L | 宽字符 | wchar_t |
u8 | UTF-8(仅用于字符串字面常量) | char |
整型字面值
后缀 | 最小匹配类型 |
---|---|
u or U | unsigned |
l or L | long |
ll or LL | long long |
浮点型字面值
后缀 | 类型 |
---|---|
f or F | float |
l or L | long double |
true和false是布尔类型字面值
nullptr是指针字面值