2.3-变量的大小与sizeof操作符

从2.1节《详解变量的定义、初始化与赋值》的学习中我们了解到,现代计算机的内存通常是按byte大小的单元进行组织的,每个单元都是唯一的标识地址,从这个意义讲,我们可以形象地把内存看成一系列文件夹/邮箱,可以用来存放和检索信息,变量就是用来访问这些文件夹/邮箱的名称。

但是,这样的类比从某方面看也是不准确的——大多数的变量实际上占用超过一个字节的内存,单个变量可能使用2个、4个甚至8个连续的内存地址。变量占用的数据类型取决于其数据类型。幸运的是,由于我们通常使用变量名而不是内存地址访问内存,所以编译器能在很大程度上对我们隐藏处理不同大小变量的细节。

了解一个变量占用多少内存有几个好处。

首先,一个变量占用越多的内存,就应当能保存越多的信息。因为每个bit只能保存0或1,所以我们说一bit能够保存两个可能的值。

2bit可以存放4个可能的值:

bit 0 bit 1
0 0
0 1
1 0
1 1

3bit可以存放8个可能的值:

bit 0 bit 1 bit 2
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

依次类推,一个n bit的变量可以存放2^n个可能的值,所以一个字节byte可以存放2^8(256)个可能的值。

变量的大小限制了其存储信息的能力,当我们接触更多不同类型的变量时会进一步了解这一点。

其次,计算机的可用内存是有限的,一旦我们声明了一个变量,只要这个变量还存在,就会占用一部分的空闲内存。由于现代计算机的内存通常很大,所以这通常不是问题(特别是只有几个变量的小程序),但是如果你的程序拥有巨量的变量(例如10,000个)或者可用内存相当有限(例如进行单片机开发时),使用1字节和8字节的变量性能开销就会是天壤之别。

C++基本数据类型的大小

接下来的问题就是如何确定变量占用内存的大小了,你可能会感到惊讶,一个给定数据类型实际上取决于编译器/计算机架构。

C++规定基本数据类型占用的最小内存如下:

种类 数据类型 最小占用内存
布尔型 bool 1 byte
字节型 char 1 byte
wchar_t 1 byte
char16_t 2 bytes C++11
char32_t 4 bytes C++11
整型 short 2 bytes
int 2 bytes
long 4 bytes
long long 8 bytes C99/C++11
浮点型 float 4 bytes
double 8 bytes
long double 8 bytes

实际计算机上的变量大小可能与此不同,为了确定数据类型的大小,C++提供了一个操作符:sizeof。sizeof操作符为一元操作符,接受参数为变量名或者数据类型,以字节为单位返回其大小,你可以编译运行以下程序以了解你计算机上的变量大小。

#include <iostream>

int main()
{
    std::cout << "bool:\t\t" << sizeof(bool) << " bytes" << std::endl;
    std::cout << "char:\t\t" << sizeof(char) << " bytes" << std::endl;
    std::cout << "wchar_t:\t" << sizeof(wchar_t) << " bytes" << std::endl;
    std::cout << "char16_t:\t" << sizeof(char16_t) << " bytes" << std::endl; // 需编译器支持C++11
    std::cout << "char32_t:\t" << sizeof(char32_t) << " bytes" << std::endl; // 需编译器支持C++11
    std::cout << "short:\t\t" << sizeof(short) << " bytes" << std::endl;
    std::cout << "int:\t\t" << sizeof(int) << " bytes" << std::endl;
    std::cout << "long:\t\t" << sizeof(long) << " bytes" << std::endl;
    std::cout << "long long:\t" << sizeof(long long) << " bytes" << std::endl; // 需编译器支持C++11
    std::cout << "float:\t\t" << sizeof(float) << " bytes" << std::endl;
    std::cout << "double:\t\t" << sizeof(double) << " bytes" << std::endl;
    std::cout << "long double:\t" << sizeof(long double) << " bytes" << std::endl;
    return 0;
}

使用Visual Studio 2013在64位机器上运行结果如下:

bool:           1 bytes
char:           1 bytes
wchar_t:        2 bytes
char16_t:       2 bytes
char32_t:       4 bytes
short:          2 bytes
int:            4 bytes
long:           4 bytes
long long:      8 bytes
float:          4 bytes
double:         8 bytes
long double:    8 bytes

使用其他编译器/计算机得到的结果可能不同,注意不可以使用sizeof(void),因为void是无大小的,这么做会产生一个编译错误。

上述程序中的’\t’是一个特殊字符,用来插入制表符,在上述例子中,我们用它来对齐输出结果。以后谈论char数据类型的时候我们会讲到\t以及其他特殊字符。

我们也可以对一个变量名使用sizeof:

int x;
std::cout << "x is " << sizeof(x) << " bytes" << std::endl;

结果如下:

x is 4 bytes

关于 “2.3-变量的大小与sizeof操作符” 的 2 个意见

评论关闭。