基本数据类型简介
本节阅读量:位、字节和内存寻址
在「对象和变量」中,我们了解到变量是用于存储信息的一段内存的名称。简单回顾一下,计算机拥有可供程序使用的随机存取存储器(RAM)。定义变量时,会为该变量预留一段内存。
内存的最小单位是二进制数字(也称为比特或位,bit),它只能保存0或1。你可以把它想象成一个传统的灯开关——灯要么关闭(0),要么打开(1),没有中间状态。如果随意查看一段内存,你看到的只会是「011010100101010」之类的组合。
内存被组织为按顺序排列的单元,每个单元都有一个内存地址(或简称地址)。就像通过街道地址可以找到对应的房屋一样,通过内存地址我们可以找到并访问特定位置的内存内容。
也许令人意外的是,在现代计算机架构中,单独的一个「比特」并没有自己唯一的内存地址。这是因为内存地址的数量是有限的,而且很少需要按位访问数据。实际上,每个内存地址保存的是1个「字节」的数据。字节是作为一个整体进行操作的一组比特。现代标准规定,一个字节(byte)由8个连续比特组成。
下图展示了一些连续的内存地址及其对应的数据字节:
由于计算机上的所有数据都只是一串比特序列,因此我们需要使用数据类型(通常简称为”类型”)来告诉编译器如何以有意义的方式解释内存中的内容。你已经见过一种数据类型的例子:整数。当我们将变量声明为整数时,就是在告诉编译器”这个变量所占用的内存块应被解释为整数值”。
当你给对象赋值时,编译器和CPU会负责将该值编码为与数据类型对应的比特序列,然后将其存储在内存中(记住:内存只能存储比特)。例如,如果你给一个整数对象赋值65,这个值就会被转换为比特序列0100 0001,并存储到分配给该对象的内存中。
反过来,当对象被求值以产生一个值时,该比特序列会被还原为原始值。也就是说,0100 0001会被转换回值65。
幸运的是,编译器和CPU承担了所有的繁重工作,因此你通常不需要关心值是如何与比特序列相互转换的。
你所需要做的就是为对象选择一种最适合你用途的数据类型。
关键点
在C++中,我们通常使用“字节大小”的数据块。
旁白
一些较旧或非标准的机器可能使用不同大小的字节(从1到48位)——不过我们通常不需要担心这一点,因为现代的事实标准是一个字节等于8位。在本教程中,我们也将假设一个字节是8位。
基本数据类型
C++内置了对许多不同数据类型的支持。这些被称为基本数据类型,但通常也被非正式地称为基本类型或内置类型。
下面是基本数据类型的列表,其中一些你已经见过:
| 类型 | 类别 | 含义 | 样例 |
|---|---|---|---|
| float / double / long double | 浮点数 | 有分数部分的数字 | 3.1415926 |
| bool | bool 整型 | true 或 false | true |
| char / wchar_t / char8_t (C++20) / char16_t (C++11) / char32_t (C++11) | 字符 整型 | 一个单独的字符 | ‘c’ |
| short int / int / long int / long long int (C++11) | 整数 整型 | 含0,正数或负数 | 42 |
| std::nullptr_t (C++11) | Null Pointer | 空指针 | nullptr |
| void | Void | 无类型 | n/a |
本章将详细介绍这些基本数据类型(std::nullptr_t除外,我们会在讨论指针时再介绍它)。C++还支持许多更复杂的类型,称为复合类型。我们将在后续章节中探讨复合类型。
旁白
大多数现代编程语言都包含基本的字符串类型(字符串是一种数据类型,用于保存字符序列,通常表示文本)。在C++中,字符串不是基本类型(而是复合类型)。但由于基本字符串用法简单且实用,我们将在「std::string简介」小节中介绍它。
后缀(_t)
在较新版本的C++中定义的许多类型(例如std::nullptr_t)使用_t后缀。这个后缀的意思是”type(类型)”,它是现代类型命名中常见的惯例。
如果你看到带_t后缀的名称,它很可能是一种类型。但也有许多类型没有_t后缀,这是由于不同版本引入时的命名不一致所致。