C++定义了一套包括算术类型(arithmetic type)和空类型(void)在内的基本数据类型。其中算术类型包含了字符、整型数、布尔值和浮点数。空类型不对应具体的值,仅用于一些特殊的场合,例如最常见的是,当函数不返回任何值时使用空类型作为返回类型。
为了给变量分配内存,C++规定在创建一个变量或者常量时,必须要指定出相应的数据类型。
第一种类型是整数型:
整型变量表示的是整数类型的数据
C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同:
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | [-2^15, 2^15-1] |
int(整型) | 4字节 | [-2^31, 2^31-1] |
long(长整型) | Windows 为4字节,Linux 为4字节(32位),8字节(64位) | [-2^31, 2^31-1] |
long long(长长整型) | 8字节 | [-2^63, 2^63-1] |
除去布尔型和扩展的字符型之外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。带符号类型可以表示正数,负数或者是0,无符号类型则仅能表示大于0的值。
类型int、short、long 和long long都是带符号的,通过在这些类型名前加 unsigned 就可以得到无符号类型,例如 unsigned long。类型 unsigned int 可以缩写成 unsigned。
与其他整型不同,字符型被分为了3种:char,signed char 和 unsigned char。需要特别注意的是:类型char和signed char 髌骨不一样。 尽管字符型有3种,但是字符的表现形式却只有两种,带符号的和不带符号的。类型char 实际上会表现为上述两种形式中的一种,具体是哪种由编译器决定。
关于取值范围的问题,如果是int,short等类型,第一个比特用来储存符号,剩余的比特用来储存值,大多数机器的字节(byte) 由8比特构成,每个比特非0即1,因此int (4个字节,32个比特) 取值范围是 [-2^31, 2^31-1]。而无符号类型中的所有比特币都用来存储值,例如8比特的unsigned char 可以表示0到255区间内的值。
如何选择类型
- 当明确知晓数值不可能为负时,选用无符号类型。
- 使用int执行整数运算。在实际应用中,short 常常显得太小而long 一般和int 有一样的尺寸。如果你的数值超过了int的取值范围,选用 long long。
- 在算式表达式中不要使用 char 和 bool ,只有在存放字符和布尔值时才使用它们。因为类型 char 在一些机器上是有符号的,而在另一些机器上又是无符号的,所以如果使用 char 进行运算特别容易初吻难题。如果你需要需用一个不大的整数,那么明确指定它的类型是 signed char 或者 unsigned char。
- 执行浮点数运算选用 double,这是因为 float 通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。事实上,对于某些机器来说,双精度甚至比单精度还快。
类型转换
unsigned char c = -1 // 假设 char 占用 8 比特, c的值为255
当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如,8比特大小的 unsigned char 可以表示 0 至 255 区间的值,如果我们赋了一个区间以外的值,则实际结果是该值对256取模后所得的余数。因此,把-1赋给8比特大小的 unsigned char 所得的结果是255。
为什么在此处c的值为255,-1%256 =255?
首先明确,此时的运算对象的类型为 unsigned char,对象类型决定了能对该对象进行的操作。
根据以往的数学知识,-1 = 256*0 -1 ,余数为 -1, 在 C++ 中我们可以得到同样的答案,提前是必须定义 -1 和 256 的数据类型为整数:
#include <iostream>
using namespace std;
int main() {
int a = -1;
int b = 256;
cout << a % b << endl;
system("pause");
}
数据类型变更,系统会报错。(在算数表示式中,不要使用char)
数据类型变更,输出为255,ps:在算数表示式中,不要使用char:
#include <iostream>
using namespace std;
int main() {
unsigned char a = -1;
int b = 256;
cout << a % b << endl;
system("pause");
}
因此,取余请参考这个公式:
a % b = a - b * floor(a / b)
其中floor(x)表示不大于x的最大整数
-1 % 256 = -1 - 256 * floor(-1/256) = -1 - 256 * (-1) = 255
signed char c2 = 256; // 假设 char 占用 8 比特,c2 的值未定义的。
当我们赋给符号类型一个超出它表示范围的值时,结果是未定义的,此时,程序可能继续工作,可能崩溃,也可能产生垃圾数据。
练习:
#include <iostream>
using namespace std;
int main() {
unsigned u = 10, u2 = 42;
cout << u2 - u << endl; //32
cout << u - u2 << endl; //4294967264
int i = 10, i2 = 42;
cout << i2 - i << endl; //32
cout << i - i2 << endl; //-32
cout << i - u << endl; //0
cout << u - i << endl; //0
system("pause");
}