程序在执行的过程中,需要在内存空间中运算、存储信息,由于数据类型各不相同,存储时需要的容量不一,不同的数据要配给不同空间大小,因而有了「数据类型」(Data type)的规范。
C++ 中基本数据类型主要区分为整数(Integer)、浮点数(Float)、字符(Character),而这几种还可以细分,如下所示:
- 整数 用来表示整数值,可以区分为 short、int、long 与 long long(C++ 11),可容纳的大小各不相同,int 至少会跟 short 一样大,long 至少会跟 int 一样大,long long 至少 64 个位。
- 浮点数 用来表示小数值,可以区分为 float、double 与 long double,越后面的类型使用的内存空间越大,精度也就越高。
- 字符 char 的 sizeof(char) 结果要是 1,基本上用来存储字符数据,但没有规定什么是字符数据,也可用来存储较小范围的整数。 与字符相关的类型,其实还有 wchar_t,C++ 11 的 char16_t、char32_t(以及 C++ 20 的 char8_t),这之后有机会再来谈。
在 C 语言文件的〈数据类型〉中谈到,在 C11 标准中,建议包括 stdint.h 程序库,使用int8_t
、int16_t
、int32_t
、int64_t
uint8_t
、uint16_t
、uint32_t
、uint64_t
等作为整数类型的定义,以避免平台依赖性的问题,在 C++ 中可以包含cstdint
来使用这些类型。
以上的数据类型在内存中占有的大小,依平台系统而有所差异,字组的大小取决于机器,在 32 位机器上通常一个字组是 4 个字节,如果想知道这些数据类型在平台上,占有的内存空间有多少,可以使用sizeof
运算符,下面这个程序是个简单示范:
#include <iostream>
using namespace std;
int main() {
cout << "\n类型\t大小(bytes)";
cout << "\nint\t" << sizeof(int);
cout << "\nlong\t" << sizeof(long);
cout << "\nfloat\t" << sizeof(float);
cout << "\ndouble\t" << sizeof(double);
cout << "\nchar\t" << sizeof(char);
cout << "\n";
return 0;
}
其中'\t'
是跳格字符,相当于在控制台中按下 Tab 键的效果,可以用来对齐下一个显示位置;以下是执行结果:
类型 大小(bytes)
int 4
long 4
float 4
double 8
char 1
由于平台不同,你的执行结果不一定会与这边相同;因为每种数据类型占有的内存大小不同,因而可以存储的数值范围也就不同。
例如在上例中,整数int
的内存空间是 4 个字节,可以存储的整数范围为 -2147483648 至 2147483647,如果存储值超出这个范围的话称之为「溢值」 (Overflow),会造成程序不可预期的结果。
整数计算范围的方式很简单,例如int
整数占 4 字节的话,可存储范围为2^32 / 2
,除以 2 是因为要分另一半存储负整数的关系,整数的最左边位被用来表示正负号,如果最左边位为 0 表示正号,若为 1 表示负号。
在 C++ 中可以使用signed
、unsigned
定义有符号、无符号整数,无符号整数最左边位不用来表示正负号,例如一个 8 位字符被用来表示整数时,可以表示数值 -128 到 127,而一个无符号字符可以表示 0 到 255 的正整数。
size_t
是个机器特定的无符号类型,定义于cstddef
标头文件,为 C 语言stddef.h
的 C++ 版本,保证够大可以容纳任何对象,若数据结构具有长度或索引概念,而且需要很大的容量,例如数组,可以使用size_t
类型变量来实现长度或索引。
用于存储整数时,char
有符号或无符号取决于编译器,可以明确使用signed char
表示有符号,这时正值与负值平均分配,unsigned char
是无符号的。
浮点数的存储方式则是分为两个部份,例如float
占四个字节的话,前三个字节用来存储假数,后一个字节存储指数,例如3.14 * 10^8
, 3.14 存储在前三字节,而 8 存储于后一字节,所以float
大致上可以存储的范围为10^38
到10^-38
(就指数来算出的),而double
可以大致存储10^308
至10^-308
之间的数值。
C++ 有bool
类型,用来表示布尔数,在程序中占一个字节,可以使用true
或false
字面常量(Literal constant)来表示,实际数值由语言实现决定,不一定对应于 1 与 0,可以使用下面这个程序来检验:
#include <iostream>
using namespace std;
int main() {
cout << "sizeof(bool)\t" << sizeof(bool) << "\n";
cout << "sizeof(true)\t" << sizeof(true) << "\n";
cout << "sizeof(false)\t" << sizeof(false) << "\n";
cout << "true\t" << true << "\n";
cout << "false\t" << false << "\n";
return 0;
}
执行结果:
sizeof(bool) 1
sizeof(true) 1
sizeof(false) 1
true 1
false 0