2.1. Primitive Built-in Types2.1. 基本内置类型C++ defines a set of arithmetic types, which represent integers, floating-point numbers, and individual characters and boolean values. In addition, there is a special type named void. The void type has no associated values and can be used in only a limited set of circumstances. The void type is most often used as the return type for a function that has no return value. C++ 定义了一组表示整数、浮点数、单个字符和布尔值的算术类型,另外还定义了一种称为 void 的特殊类型。void 类型没有对应的值,仅用在有限的一些情况下,通常用作无返回值函数的返回类型。 The size of the arithmetic types varies across machines. By size, we mean the number of bits used to represent the type. The standard guarantees a minimum size for each of the arithmetic types, but it does not prevent compilers from using larger sizes. Indeed, almost all compilers use a larger size for int than is strictly required. Table 2.1 (p. 36) lists the built-in arithmetic types and the associated minimum sizes. 算术类型的存储空间依机器而定。这里的存储空间是指用来表示该类型的位(bit)数。C++标准规定了每个算术类型的最小存储空间,但它并不阻止编译器使用更大的存储空间。事实上,对于int类型,几乎所有的编译器使用的存储空间都比所要求的大。int表 2.1 列出了内置算术类型及其对应的最小存储空间。 Table 2.1. C++: Arithmetic Types表 2.1. C++ 算术类型
2.1.1. Integral Types2.1.1. 整型The arithmetic types that represent integers, characters, and boolean values are collectively referred to as the integral types. 表示整数、字符和布尔值的算术类型合称为整型。 There are two character types: char and wchar_t. The char type is guaranteed to be big enough to hold numeric values that correspond to any character in the machine's basic character set. As a result, chars are usually a single machine byte. The wchar_t type is used for extended character sets, such as those used for Chinese and Japanese, in which some characters cannot be represented within a single char. 字符类型有两种:char 和 wchar_t。char 类型保证了有足够的空间,能够存储机器基本字符集中任何字符相应的数值,因此,char 类型通常是单个机器字节(byte)。wchar_t 类型用于扩展字符集,比如汉字和日语,这些字符集中的一些字符不能用单个 char 表示。 The types short, int, and long represent integer values of potentially different sizes. Typically, shorts are represented in half a machine word, ints in a machine word, and longs in either one or two machine words (on 32-bit machines, ints and longs are usually the same size). short、int 和 long 类型都表示整型值,存储空间的大小不同。一般, short 类型为半个机器字长,int 类型为一个机器字长,而 long 类型为一个或两个机器字长(在 32 位机器中 int 类型和 long 类型通常字长是相同的)。
The type bool represents the truth values, true and false. We can assign any of the arithmetic types to a bool. An arithmetic type with value 0 yields a bool that holds false. Any nonzero value is treated as true. bool 类型表示真值 true 和 false。可以将算术类型的任何值赋给 bool 对象。0 值算术类型代表 false,任何非 0 的值都代表 true。 Signed and Unsigned Types带符号和无符号类型The integral types, except the boolean type, may be either signed or unsigned. As its name suggests, a signed type can represent both negative and positive numbers (including zero), whereas an unsigned type represents only values greater than or equal to zero. 除 bool 类型外,整型可以是带符号的(signed)也可以是无符号的(unsigned)。顾名思义,带符号类型可以表示正数也可以表示负数(包括 0),而无符号型只能表示大于或等于 0 的数。 The integers, int, short, and long, are all signed by default. To get an unsigned type, the type must be specified as unsigned, such as unsigned long. The unsigned int type may be abbreviated as unsigned. That is, unsigned with no other type implies unsigned int. 整型 int、short 和 long 都默认为带符号型。要获得无符号型则必须指定该类型为 unsigned,比如 unsigned long。unsigned int 类型可以简写为 unsigned,也就是说,unsigned 后不加其他类型说明符意味着是 unsigned int 。 Unlike the other integral types, there are three distinct types for char: plain char, signed char, and unsigned char. Although there are three distinct types, there are only two ways a char can be represented. The char type is respresented using either the signed char or unsigned char version. Which representation is used for char varies by compiler. 和其他整型不同,char 有三种不同的类型:plain char 、unsigned char 和 signed char。虽然 char 有三种不同的类型,但只有两种表示方式。可以使用 unsigned char 或 signed char 表示 char 类型。使用哪种 char 表示方式由编译器而定。 How Integral Values Are Represented整型值的表示In an unsigned type, all the bits represent the value. If a type is defined for a particular machine to use 8 bits, then the unsigned version of this type could hold the values 0 through 255. 无符号型中,所有的位都表示数值。如果在某种机器中,定义一种类型使用 8 位表示,那么这种类型的 unsigned 型可以取值 0 到 255。 The C++ standard does not define how signed types are represented at the bit level. Instead, each compiler is free to decide how it will represent signed types. These representations can affect the range of values that a signed type can hold. We are guaranteed that an 8-bit signed type will hold at least the values from 127 through 127; many implementations allow values from 128 through 127. C++ 标准并未定义 signed 类型如何用位来表示,而是由每个编译器自由决定如何表示 signed 类型。这些表示方式会影响 signed 类型的取值范围。8 位 signed 类型的取值肯定至少是从 -127 到 127,但也有许多实现允许取值从 -128 到 127。 Under the most common strategy for representing signed integral types, we can view one of the bits as a sign bit. Whenever the sign bit is 1, the value is negative; when it is 0, the value is either 0 or a positive number. An 8-bit integral signed type represented using a sign-bit can hold values from 128 through 127. 表示 signed 整型类型最常见的策略是用其中一个位作为符号位。符号位为 1,值就为负数;符号位为 0,值就为 0 或正数。一个 signed 整型取值是从 -128 到 127。 Assignment to Integral Types整型的赋值The type of an object determines the values that the object can hold. This fact raises the question of what happens when one tries to assign a value outside the allowable range to an object of a given type. The answer depends on whether the type is signed or unsigned. 对象的类型决定对象的取值。这会引起一个疑问:当我们试着把一个超出其取值范围的值赋给一个指定类型的对象时,结果会怎样呢?答案取决于这种类型是 signed 还是 unsigned 的。 For unsigned types, the compiler must adjust the out-of-range value so that it will fit. The compiler does so by taking the remainder of the value modulo the number of distinct values the unsigned target type can hold. An object that is an 8-bit unsigned char, for example, can hold values from 0 through 255 inclusive. If we assign a value outside this range, the compiler actually assigns the remainder of the value modulo 256. For example, we might attempt to assign the value 336 to an 8-bit signed char. If we try to store 336 in our 8-bit unsigned char, the actual value assigned will be 80, because 80 is equal to 336 modulo 256. 对于 unsigned 类型来说,编译器必须调整越界值使其满足要求。编译器会将该值对 unsigned 类型的可能取值数目求模,然后取所得值。比如 8 位的 unsigned char,其取值范围从 0 到 255(包括 255)。如果赋给超出这个范围的值,那么编译器将会取该值对 256 求模后的值。例如,如果试图将 336 存储到 8 位的 unsigned char 中,则实际赋值为 80,因为 80 是 336 对 256 求模后的值。 For the unsigned types, a negative value is always out of range. An object of unsigned type may never hold a negative value. Some languages make it illegal to assign a negative value to an unsigned type, but C++ does not. 对于 unsigned 类型来说,负数总是超出其取值范围。unsigned 类型的对象可能永远不会保存负数。有些语言中将负数赋给 unsigned 类型是非法的,但在 C++ 中这是合法的。
When assigning an out-of-range value to a signed type, it is up to the compiler to decide what value to assign. In practice, many compilers treat signed types similarly to how they are required to treat unsigned types. That is, they do the assignment as the remainder modulo the size of the type. However, we are not guaranteed that the compiler will do so for the signed types. 当将超过取值范围的值赋给 signed 类型时,由编译器决定实际赋的值。在实际操作中,很多的编译器处理 signed 类型的方式和 unsigned 类型类似。也就是说,赋值时是取该值对该类型取值数目求模后的值。然而我们不能保证编译器都会这样处理 signed 类型。 2.1.2. Floating-Point Types2.1.2. 浮点型The types float, double, and long double represent floating-point single-, double-, and extended-precision values. Typically, floats are represented in one word (32 bits), doubles in two words (64 bits), and long double in either three or four words (96 or 128 bits). The size of the type determines the number of significant digits a floating-point value might contain. 类型 float、 double 和 long double 分别表示单精度浮点数、双精度浮点数和扩展精度浮点数。一般 float 类型用一个字(32 位)来表示,double 类型用两个字(64 位)来表示,long double 类型用三个或四个字(96 或 128 位)来表示。类型的取值范围决定了浮点数所含的有效数字位数。
|
Advice: Using the Built-in Arithmetic Types建议:使用内置算术类型The number of integral types in C++ can be bewildering. C++, like C, is designed to let programs get close to the hardware when necessary, and the integral types are defined to cater to the peculiarities of various kinds of hardware. Most programmers can (and should) ignore these complexities by restricting the types they actually use. C++ 中整型数有点令人迷惑不解。就像 C 语言一样,C++ 被设计成允许程序在必要时直接处理硬件,因此整型被定义成满足各种各样硬件的特性。大多数程序员可以(应该)通过限制实际使用的类型来忽略这些复杂性。 In practice, many uses of integers involve counting. For example, programs often count the number of elements in a data structure such as a vector or an array. We'll see in Chapters 3 and 4 that the library defines a set of types to use when dealing with the size of an object. When counting such elements it is always right to use the library-defined type intended for this purpose. When counting in other circumstances, it is usually right to use an unsigned value. Doing so avoids the possibility that a value that is too large to fit results in a (seemingly) negative result. 实际上,许多人用整型进行计数。例如:程序经常计算像 vector 或数组这种数据结构的元素个数。在第三章和第四章中,我们将看到标准库定义了一组类型用于统计对象的大小。因此,当计数这些元素时使用标准库定义的类型总是正确的。其他情况下,使用 unsigned 类型比较明智,可以避免值越界导致结果为负数的可能性。 When performing integer arithmetic, it is rarely right to use shorts. In most programs, using shorts leads to mysterious bugs when a value is assigned to a short that is bigger than the largest number it can hold. What happens depends on the machine, but typically the value "wraps around" so that a number too large to fit turns into a large negative number. For the same reason, even though char is an integral type, the char type should be used to hold characters and not for computation. The fact that char is signed on some implementations and unsigned on others makes it problematic to use it as a computational type. 当执行整型算术运算时,很少使用 short 类型。大多数程序中,使用 short 类型可能会隐含赋值越界的错误。这个错误会产生什么后果将取决于所使用的机器。比较典型的情况是值“截断(wrap around)”以至于因越界而变成很大的负数。同样的道理,虽然 char 类型是整型,但是 char 类型通常用来存储字符而不用于计算。事实上,在某些应用中 char 类型被当作 signed 类型,在另外一些应用中则被当作 unsigned 类型,因此把 char 类型作为计算类型使用时容易出问题。 On most machines, integer calculations can safely use int. Technically speaking, an int can be as small as 16 bitstoo small for most purposes. In practice, almost all general-purpose machines use 32-bits for ints, which is often the same size used for long. The difficulty in deciding whether to use int or long occurs on machines that have 32-bit ints and 64-bit longs. On such machines, the run-time cost of doing arithmetic with longs can be considerably greater than doing the same calculation using a 32-bit int. Deciding whether to use int or long requires detailed understanding of the program and the actual run-time performance cost of using long versus int. 在大多数机器上,使用 int 类型进行整型计算不易出错。就技术上而言,int 类型用 16 位表示——这对大多数应用来说太小了。实际应用中,大多数通用机器都是使用和 long 类型一样长的 32 位来表示 int 类型。整型运算时,用 32 位表示 int 类型和用 64 位表示 long 类型的机器会出现应该选择 int 类型还是 long 类型的难题。在这些机器上,用 long 类型进行计算所付出的运行时代价远远高于用 int 类型进行同样计算的代价,所以选择类型前要先了解程序的细节并且比较 long 类型与 int 类型的实际运行时性能代价。 Determining which floating-point type to use is easier: It is almost always right to use double. The loss of precision implicit in float is significant, whereas the cost of double precision calculations versus single precision is negligible. In fact, on some machines, double precision is faster than single. The precision offered by long double usually is unnecessary and often entails considerable extra run-time cost. 决定使用哪种浮点型就容易多了:使用 double 类型基本上不会有错。在 float 类型中隐式的精度损失是不能忽视的,而 double 类型精度代价相对于 float 类型精度代价可以忽略。事实上,有些机器上,double 类型比 float 类型的计算要快得多。long double 类型提供的精度通常没有必要,而且还需要承担额外的运行代价。 |