(博文参考书籍《C++ Primer 中文版》,摘录易忘知识点和容易混淆的内容)
C++定义了一套包括算术类型(arithmetic type)和空类型(void)在内的基本数据类型。
其中算术类型包含:字符、整数型、布尔值、浮点数。
空类型不对应具体的值,仅用于一些特定场合,常见的如:函数不返回任何值是,使用空类型作为函数的返回类型。
一、算术类型
算术类型分为两类:整形(intergral type,包括字符和布尔类型在内)、浮点型。
算术类型的尺寸(也就是该类型数据所占的比特数)在不同机器上有所差别。下方列出了C++标准规定的尺寸的最小值,同时允许编译器赋予这些类型更大的尺寸。某一类型所占的比特数不同,他所能表示的数据范围也不一样。
类型
含义
最小尺寸
数据范围
bool
布尔类型
未定义
char
字符
8位
带符号:signed char -128 ~127
无符号:unsiged char 0~255
wchar_t
宽字符
16位
char16_t
Unicode字符
16位
char32_t
Unicode字符
32位
short
短整型
16位
-2的8次方 ~ 2的8次方-1
int
整型
16位
-2的8次方 ~ 2的8次方-1
long
长整型
32位
-2的16次方 ~ 2的16次方-1
long long
长整型
64位
-2的32次方 ~ 2的32次方-1
float
单精度浮点型
6位有效数字
double
双精度浮点型
10位有效数字
long double
扩展精度浮点型
10位有效数字
布尔类型的取值是真(true)或假(false)。
基本的字符类型是char,一个char的空间应确保可以存放机器基本字符集中任意字符对应的数字值。也就是说,一个char的大小和一个机器字节一样。
内置类型的机器实现
计算机以比特序列存储数据,每个比特非0即1。
大多数的计算机以2的整数次幂个比特作为块来处理内存,可寻址的最小内存块成为“字节(byte)”,存储的基本单元称为“字(word)”,它通常由几个字节组成。C++语言中,一个字节要至少能容纳机器基本字符集中的字符。大多数机器的字节由8比特构成,字则由32或64比特构成,也就是4或8字节。
大多数计算机将内存中的每个字节与一个数字(被称为“地址(address)”)关联起来,在一个字节位8比特、字为32比特的机器上,我们可能看到一个字的内存区域如下所示
地址
内容
736424
1 0 0 1 0 1 1 0
736425
0 0 1 1 0 1 0 1
736426
0 1 0 1 0 0 1 1
736427
0 1 1 0 0 1 0 0
我们能够使用地址来表述这个地址开始的大小不同的比特串,为了赋予内存中某个地址明确的含义,必须首先知道存储在该地址的数据的类型。类型决定了数据所占的比特数以及该如何解释这些比特的内容。
带符号类型和无符号类型
除去布尔型和扩展的字符型之外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。类型int、short、long 和long long都是带符号的,通过在这些类型名前添加unsigned即可得到无符号类型。类型 unsigned int 可以缩写为 unsigned.
与其他整型不同,字符型被分为了三种:char、 singed char 和unsigned char。特别需要注意的是:类型char 和类型 signed char并不一样。尽管字符型有三种,但是字符的表现形式却只有两种,带符号的和无符号的。类型char 实际上会表现为上述两种形式中的一种,具体是哪种由编译器决定。
二、自动类型转换
1、非布尔型 --> 布尔型:初始值为0则为false,否则为true
2、布尔型 --> 非布尔型:true --> 1; false --> 0
3、整数值 --> 浮点型:小数部分记为0
4、负值 --> 无符号型:结果为初始值对无符号类型表示数值总数取模后的余数。列如:unsigned char 可以表示0~255,我们给个-1,就是对256取模,得到余数255.
这里我们来看一个代码示例:通过控制变量递减的方式把10到0的数字降序输出
#include <iostream>
using namespace std;
//倒序输出10-0
void DescPrintTenToOne()
{
cout << "带符号的" << endl;
for (int i = 10;i >= 0; i--)//正确,如我们预取的效果一样
{
cout << i << endl;
}
cout << "无符号的" << endl;
for (unsigned j = 10; j >= 0; j--) //由于负值向无符号转换,进入了死循环
{
cout << j << endl;
}
}
int main()
{
DescPrintTenToOne();
return 0;
}
下面我们看一下控制台的打印效果
5、当我们给带符号类型一个超出它表示范围的值时,结果是未定义的(undefined)。此时,程序可能继续工作、可能崩溃、也可能生成垃圾数据