C++的基本数据类型:算数类型和空类型。
算数类型:字符、整型数、布尔值、浮点数。算数类型又可以分为整型和浮点型。
C++为算数类型定义了最小尺寸,编译器可以赋予这些类型更大的尺寸:
bool(布尔类型)未定义
char(字符) 8位。
wchat_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位有效数字,用三或四个字来表示。
(1)一个char的大小应该确保可以存放机器基本字符集中的任意一个字符,所以一个char等于一个机器字节的大小。一个wchar_t,char16_t,char32_t等用于扩展字符集,必须确保可以存放机器最大扩展字符集中的任意一个字符。其中char16_t和char32_t为Unicode字符集服务。Unicode字符集为每一种语言的每个字符定义了统一且唯一的二进制编码。
(2)long long是C++11中新定义的。
C++是如何存这些类型的:
可寻址的最小内存块成为字节,存储的基本单位是字,字由几个字节组成。大多数机器字节由8比特构成,字由32或64比特构成,也就是4或8字节。这就是我们所说的32位64位。一个地址代表一个字节,每个字节的8位存放内容。
736424 00111011
736425 01000100
736426 10101110
736427 01001010
带符号类型和无符号类型:
整型中除了布尔类型和扩展的字符型之外,其他整型可以划分为带符号的和无符号的。其中unsigned int可以缩写为unsigned。
字符型被分为三种:char、signed char和unsigned char。虽然有三种,但是字符的表现形式只有两种,带符号的和无符号的。char表现为哪一种,由编译器决定。
无符号类型中所有比特都用来存值。
如何选择类型:
当明确知道不可能为负数时,用无符号类型。
对于int:short太小,long一般和int一样大。如果超过了int用long long最好。
算术表达式中尽量不用char和bool。因为char不一定是有符号的还是无符号的,这个根据编译器决定。
浮点数用double不用float。
类型转换:
理解这几个例子:
(1)bool b = 42; //b为真
(2)int i = b; // i为1
(3)i = 3.14 // i为3
(4)double pi = i; // pi为3.0
(5)unsigned char c = -1; // 假设char占8比特,c的值为255
(6)signed char c2 = 256; // 假设char占8比特,c2的值是未定义的
前面几个好理解。对于(5),当赋给无符号类型一个超出他的范围时,结果是初始值对无符号类型表示数值总数取模后的余数。例如8比特的unsigned char可以表示0-255之间的数,如果赋给他一个这个区间之外的值,结果就是该值对256取模后所得的余数。因此把-1赋给8比特大小的unsigned char所得的结果是255.。至于为什么取模运算结果是255,可以理解为:取模运算时,对于负数,应该加上被除数的整数倍,使结果大于或等于0之后再进行取模。即:(-1)%256 = (-1 + 256)%256 = 255。如果从计算机存储的角度理解为什么这里是255,由于负数在计算机里以补码的形式存储,所以在这里-1存储为11111111,变成无符号数的话这就是255.
对于(6),当赋给带符号类型一个超出它的表示范围的值时,结果是未定义的。此时程序可能继续工作可能崩溃。
对于含有无符号类型的表达式:
当一个表达式中既有int又有无符号数,int值就会转换成无符号数,这时候很容易出错!把负数转换成无符号数类似于直接给无符号数一个负值,结果等于这个负数加上无符号数的模,无符号数永远不会小于0.