前面多次提及,由于一些类型使用的字节数在C++标准中没有指定,因此由编译器指定。那么就有可能需要知道某个变量类型在编译器中占据多少字节。这些信息可以从编译器的说明文档中找到,也可以使用sizeof运算符通过编程来获得。
sizeof是一个一元运算符,带一个操作数。它返回一个整数值,表示某个变量或类型占用的内存量。sizeof返回的值实际上计量了多个char类型的字节数,但因为char类型的变量占用一个字节,所以返回的值是操作数占用的字节数。
要获得type类型的变量占用的字节数,可以使用表达式sizeof(type)。所以,下面的语句可以输出int类型的变量占用的字节数:
std::cout << std::endl
<< "Size of type int is "
<< sizeof(int); //Output the size of type int
表达式sizeof(int)返回声明为int类型的实体占用的字节数。可以用这种方式确定任何数据类型占用的字节数。要获得long double值占用的字节数,可以编写下面的代码:
std::cout << std::endl
<< "Size of type long double is "
<< sizeof(long double); //Output the size of type long double
还可以把sizeof运算符应用于某个变量,甚至应用于表达式。在这种情况下,表达式不必放在括号中,当然也可以加上括号。下面的例子会输出变量number占用的字节数:
long number=999999999;
std::cout << std::endl
<< "Size of the variable number is "
<< sizeof number; //Output the size of a variable
sizeof运算符返回的值是一个整数,但实际上它是size_t类型。这不是什么新类型,其名称size_t在标准头文件中定义为一种基本整数类型的同义词,通常是unsigned int类型。因为这是一个同义词,而不是标准库中一个实体的名称,所以也可以使用它。那么,为什么要使用另一个不同的类型名,为什么不叫作unsigned int类型?
指定由sizeof运算符返回的类型的原因是该类型的建立非常灵活。sizeof运算符总是返回一个size_t类型的值,编译器会把它定义为unsigned int类型,但这是不必要的。如果这可能出于为某个硬件平台开发C++编译器的人员的方便,以便把size_t类型定义为与其他整数类型等价。这不会影响代码,因为假定其类型是size_t。本章的后面将介绍如何为已有的类型定义另一个同义词。size_t中的t表示type,所以选择这个名称表示类型占用的字节数。
程序示例3.2—— 确定数据类型占用的字节数
很容易编写一个程序,列出前面介绍的所有数据类型占用的字节数:
//Program 3.2 Finding the sizes of data types
#include <iostream>
using std::cout;
using std::endl;
int main() {
//Output the sizes for integer types
cout << endl
<< "Size of type char is"
<< sizeof(char);
cout << endl
<< "Size of type short is "
<< sizeof(short);
cout << endl
<< "Size of type int is "
<< sizeof(int);
cout << endl
<< "Size of type long is "
<< sizeof(long);
//Output the sizes for floating-point types
cout << endl
<< "Size of type float is "
<< sizeof(float);
cout << endl
<< "Size of type double is "
<< sizeof(double);
cout << endl
<< "Size of type long double is "
<< sizeof(long double);
cout << endl;
return 0;
}
该程序的输出如下:
Size of type char is 1
Size of type short is 2
Size of type int is 4
Size of type long is 4
Size of type float is 4
Size of type double is 8
Size of type long double is 8
可以修改这个程序,使用sizeof运算符获得示例变量和表达式占用的字节数。
确定数值的上下限
有时希望了解某一类型除了其占用的字节数之外的其他信息。例如希望了解该类型能包含的数值的上下限。标准头文件<limits>包含所有标准数据类型的上下限信息。该信息是通过每种类型的类来提供的,因为现在还没有讨论到类,所以其工作方式目前就不是很明显了。但是,这里将介绍如何使用头文件<limits>提供的功能获得该信息,至于具体的说明将在第13章讨论类时描述。
下面举一个例子。要显示可以存储在double类型的变量中的最大值,可以使用下面的语句:
std::cout << std::endl
<< "Maximum value of type double is "
<< std::numeric_limits<double>::max();
表达式std::numeric_limits<double>::max()输出了我们希望的值。把不同的类型名称放在尖括号中,就可以得到其他数据类型的最大值,还可以用min()代替max()来获得最小值,但整数和浮点数类型的最小值的含义是不同的。对于整数类型,min()会得到真正的最小值,即带符号的整数类型的负数。对于浮点数类型,min()会返回可以存储的最小正数。
可以检索出各种类型的许多其他信息。例如,下面的表达式就返回二进制数字的位数:
std::numeric_limits<类型名>::digits
只需把自己感兴趣的类型名插入到尖括号中即可。对于浮点数类型,就会获得尾数中二进制数字的位数;对于带符号的整数类型,就可以获得除符号位之外的二进制数字的位数。
下面编写一个小程序来显示数值数据类型的最大值和最小值。
程序示例3.3—— 确定最大值和最小值
下面是程序代码:
//Program 3.3 Finding maximum and minimum values for data types
#include <limits>
#include <iostream>
using std::cout;
using std::endl;
using std::numeric_limits;
int main() {
cout << endl
<< "The range for type short is from "
<< numeric_limits<short>::min()
<< " to "
<< numeric_limits<short>::max();
cout << endl
<< "The range for type int is from "
<< numeric_limits<int>::min()
<< " to "
<< numeric_limits<int>::max();
cout << endl
<< "The range for type long is from "
<< numeric_limits<long>::min()
<< " to "
<< numeric_limits<long>::max();
cout << endl
<< "The range for type float is from "
<< numeric_limits<float>::min()
<< " to "
<< numeric_limits<float>::max();
cout << endl
<< "The range for type double is from "
<< numeric_limits<double>::min()
<< " to "
<< numeric_limits<double>::max();
cout << endl
<< "The range for type long double is from "
<< numeric_limits<long double>::min()
<< " to "
<< numeric_limits <long double>::max();
cout << endl;
return 0;
}
该程序的执行结果如下:
The range for type short is from -32768 to 32767
The range for type int is from -2147483648 to 2147483647
The range for type long is from -2147483648 to 2147483647
The range for type float is from 1.17549e-038 to 3.40282e+038
The range for type double is from 2.22507e-308 to 1.79769e+308
The range for type long double is from 2.22507e-308 to 1.79769e+308
例子的说明
这是上一节内容的直接应用。使用本例的方法得到的值有一个类型,所以在使用它们时编译器会对它们进行类型检查。
刚才说过,数值数据类型的取值范围也可以用继承C语言的头文件中的宏来定义。<cfloat>头文件定义了浮点数上下限的符号,<climits>头文件定义了整数类型上下限的符号。例如,在<climits>头文件中,符号INT_MAX表示int类型的数值的最大值,而SCHAR_MIN表示signed char值的最小值。其他类型还有type_MAX和type_MIN符号。但是,这些都只是编译器在代码中用对应的数字替换字面量的符号。因此,在运行期间访问类型的上下限时,最好使用runtime_limits<>机制





