Appearance
数据类型
基础知识
使用编程语言进行编程时,需要用到各种变量来存储各种信息。
变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。
您可能需要存储各种数据类型(比如字符型、宽字符型、整型、浮点型、双浮点型、布尔型等)的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么。
在这里讲一句较为本质的提示,计算机中实际并没有int float double char
之分,计算机只有 0 1 的电子状态,我们定义的变量会放在内存或是其他地方,其本质状态仍然是 010101000101 这样的数据,而数据类型只是这些数据读取的方式,比如int
对 0101010101 的读取方式遵循二进制向十进制的转换方式,但是如果我们以float
方式去读取这串数据,得到的结果很大程度上将会完全不同,而这也是后面你可能会遇见的类型转换所遵循的基本机理
基本内置类型
C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。
下表列出了七种基本的 C++ 数据类型:
类型 | 关键字 |
---|---|
布尔型 | bool |
字符型 | char |
整型 | int |
浮点型 | float |
双浮点型 | double |
无类型 | void |
宽字符型 | wchar_t |
其实 wchar_t
是这样来的:typedef short int wchar_t;
所以 wchar_t
实际上的空间是和 short int
一样。
类型修饰
一些基本类型可以使用一个或多个类型修饰符进行修饰: signed
unsigned
short
long
类型大小
下表显示了各种变量类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值。
TIP
一个字节Byte
为八个二进制位Bit
。
类型 | 字节 Byte | 范围 |
---|---|---|
char | 1 | -128 到 127 或者 0 到 255 |
unsigned char | 1 | 0 到 255 |
signed char | 1 | -128 到 127 |
int | 4 | -2147483648 到 2147483647 |
unsigned int | 4 | 0 到 4294967295 |
signed int | 4 | -2147483648 到 2147483647 |
short int | 2 | -32768 到 32767 |
unsigned short int | 2 | 0 到 65,535 |
signed short int | 2 | -32768 到 32767 |
long int | 4 | -2147483648 到 2147483647 |
signed long int | 8 | -2147483648 到 2147483647 |
unsigned long int | 8 | 0 到 4294967295 |
float | 4 | 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字) |
double | 8 | 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字) |
long double | 16 | 长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。 |
wchar_t | 2 或 4 | 1 个宽字符 |
TIP
默认情况下,int
、short
、long
都是带符号的,即 signed
long int
8 个字节,int
都是 4 个字节,早期的 C 编译器定义了 long int
占用 4 个字节,int
占用 2 个字节,新版的 C/C++ 标准兼容了早期的这一设定(现在的 long int
也是 4 个字节)。不过现在在 16 位里面int
是 2 个字节,在 32 位里面是 4 个字节,单纯的int
是会随着机器位数而变化的,但是如果加上了限定符long
、short
,那么位数就不会变化,可移植性也有很大提升
当然,单单在理论上比较数据大小仍然有点抽象,我们试试看自己写一些代码来展示数据的大小吧。
你可能并不理解下面代码中cout
以及跟在后面的<<
符号代表什么意义,不过没关系,目前只用知道它负责向控制台输出数据
本实例使用了 endl
,这将在指定的字符之后插入一个换行符\n
sizeof()
运算用来获取各种数据类型的大小
\t
是制表符,相当于键盘按键Tab
,这些具体的格式符号将会在后续介绍
Cpp
#include<iostream>
#include <limits>
using namespace std;
int main()
{
/* 这里使用了 limits 库提供的属性来计算,
涉及到泛型编程,目前不必知道其基本机理,
只用知道它能给出传入数据类型的一些属性,
比如下面我们访问了 max min 等属性,得到 bool 数据类型能接受的最大最小值*/
cout << "bool 所占字节数:" << sizeof(bool) << "\t"
<< "最大值:" << (numeric_limits<bool>::max)() << "\t"
<< "最小值:" << (numeric_limits<bool>::min)() << endl;
return 0;
}
当上面的代码被编译和执行时,它会产生以下的结果
txt
bool 所占字节数:1 最大值:1 最小值:0
TIP
试试看,把上面代码里面的所有 bool
改成你想了解的数据类型,比如char int float double
,实际操作你的代码,让你印象深刻些,这也是在培养合格程序员所最为重要的实操能力
typedef
您可以使用 typedef
为一个已有的类型取一个新的名字。这常用于在结构体编程中使用。
这是使用 typedef
定义一个新类型的语法:typedef type newname;
例如,下面的语句会告诉编译器,feet
是 int
的另一个名称:typedef int feet;
现在,下面的声明是完全合法的,它创建了一个整型变量 distance:feet distance;
枚举类型
枚举类型(enumeration)是 C++ 中的一种派生数据类型,它是由用户定义的若干枚举常量的集合。
如果一个变量只有几种可能的值,可以定义为枚举类型。
所谓"枚举"是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。
创建枚举,需要使用关键字 enum
。
枚举类型的一般形式为:
enum 枚举名 { 标识符[=整型常数], 标识符[=整型常数], ...标识符[=整型常数] } 枚举变量;
如果枚举没有初始化, 即省掉 "=整型常数"
时,则从第一个标识符开始。
例如,下面的代码定义了一个颜色枚举,变量 c
的类型为 color
。最后,c
被赋值为 "blue"
。
Cpp
enum color { red, green, blue } c;
c = blue;
默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推。
但是,您也可以给名称赋予一个特殊的值,只需要添加一个初始值即可。
例如,在下面的枚举中,green
的值为 5。
cpp
enum color { red, green=5, blue };
在这里,blue
的值为 6,因为默认情况下,每个名称都会比它前面一个名称大 1,但 red
的值依然为 0。