Team LiB
Previous Section Next Section

5.1. Arithmetic Operators

5.1. 算术操作符

Unless noted otherwise, these operators may be applied to any of the arithmetic types (Section 2.1, p. 34), or any type that can be converted to an arithmetic type.

除非特别说明,表5-1所示操作符可用于任意算术类型(第 2.1 节)或者任何可转换为算术类型的数据类型。

The table groups the operators by their precedencethe unary operators have the highest precedence, then the multiplication and division operators, and then the binary addition and subtraction operators. Operators of higher precedence group more tightly than do operators with lower precedence. These operators are all left associative, meaning that they group left to right when the precedence levels are the same.

表 5.1 按优先级来对操作符进行分组——一元操作符优先级最高,其次是乘、除操作,接着是二元的加、减法操作。高优先级的操作符要比低优先级的结合得更紧密。这些算术操作符都是左结合,这就意味着当操作符的优先级相同时,这些操作符从左向右依次与操作数结合。

Table 5.1. Arithmetic Operators
表 5.1. 算术操作符

Operator

操作符

Function

功能

Use

用法

+

unary plus(一元正号)

+ expr

-

unary minus(一元负号)

- expr

*

multiplication(乘法)

expr * expr

/

division(除法)

expr / expr

%

remainder(求余)

expr % expr

+

addition(加法)

expr + expr

-

subtraction(减法)

expr - expr


Applying precedence and associativity to the previous expression:

对于前述表达式

     5 + 10 * 20/2;

we can see that the operands to the multiplication operator (*) are 10 and 20. The result of that expression and 2 are the operands to the division operator (/). The result of that division and 5 are the operands to the addition operator (+).

考虑优先级与结合性,可知该表达式先做乘法( *)操作,其操作数为 1020,然后以该操作的结果和 2 为操作数做除法(/)操作,其结果最后与操作数 5做加法( +)操作。

The unary minus operator has the obvious meaning. It negates its operand:

一元负号操作符具有直观的含义,它对其操作数取负:

     int i = 1024;
     int k = -i; //  negates the value of its operand

Unary plus returns the operand itself. It makes no change to its operand.

一元正号操作符则返回操作数本身,对操作数不作任何修改。

Caution: Overflow and Other Arithmetic Exceptions

警告:溢出和其他算术异常

The result of evaluating some arithmetic expressions is undefined. Some expressions are undefined due to the nature of mathematicsfor example, division by zero. Others are undefined due to the nature of computerssuch as overflow, in which a value is computed that is too large for its type.

某些算术表达式的求解结果未定义,其中一部分由数学特性引起,例如除零操作;其他则归咎于计算机特性,如溢出:计算出的数值超出了其类型的表示范围。

Consider a machine on which shorts are 16 bits. In that case, the maximum short is 32767. Given only 16 bits, the following compound assignment overflows:

考虑某台机器,其 short 类型为 16 位,能表示的最大值是 32767。假设 short 类型只有 16 位,下面的复合赋值操作将会溢出:

     // max value if shorts are 8 bits
     short short_value = 32767;
     short ival = 1;
     // this calculation overflows
     short_value += ival;
     cout << "short_value: " << short_value << endl;

Representing a signed value of 32768 requires 17 bits, but only 16 are available. On many systems, there is no compile-time or run-time warning when an overflow might occur. The actual value put into short_value varies across different machines. On our system the program completes and writes

表示 32768 这个有符号数需 17 位的存储空间,但是这里仅有 16 位,于是导致溢出现象的发生,此时,许多系统都不会给出编译时或运行时的警告。对于不同的机器,上述例子的 short_value 变量真正获得的值不尽相同。在我们的系统上执行该程序后将得到:

     short_value: -32768

The value "wrapped around:" The sign bit, which had been 0, was set to 1, resulting in a negative value. Because the arithmetic types have limited size, it is always possible for some calculations to overflow. Adhering to the recommendations from the "Advice" box on page 38 can help avoid such problems.

其值“截断(wrapped around)”,将符号位的值由 0 设为 1,于是结果变为负数。因为算术类型具有有限的长度,因此计算后溢出的现象常常发生。遵循第 2.2 节建议框中给出的建议将有助于避免此类问题。


The binary + and - operators may also be applied to pointer values. The use of these operators with pointers was described in Section 4.2.4 (p. 123).

二元 +- 操作符也可用于指针值,对指针使用这些操作符的用法将在第 4.2.4 节介绍。

The arithmetic operators, +, -, *, and / have their obvious meanings: addition, subtraction, multiplication, and division. Division between integers results in an integer. If the quotient contains a fractional part, it is truncated:

算术操作符 +-*/ 具有直观的含义:加法、减法、乘法和除法。对两个整数做除法,结果仍为整数,如果它的商包含小数部分,则小数部分会被截除:

     int ival1 = 21/6;  //  integral result obtained by truncating the remainder
     int ival2 = 21/7;  //  no remainder, result is an integral value

Both ival1 and ival2 are initialized with a value of 3.

ival1ival2 均被初始化为 3

The % operator is known as the "remainder" or the "modulus" operator. It computes the remainder of dividing the left-hand operand by the right-hand operand. This operator can be applied only to operands of the integral types: bool, char, short, int, long, and their associated unsigned types:

操作符 % 称为“求余(remainder)”或“求模(modulus)”操作符,用于计算左操作数除以右操作数的余数。该操作符的操作数只能为整型,包括 boolcharshortintlong 类型,以及对应的 unsigned 类型:

     int ival = 42;
     double dval = 3.14;
     ival % 12;   //  ok: returns 6
     ival % dval; //  error: floating point operand

For both division (/) and modulus(%), when both operands are positive, the result is positive (or zero). If both operands are negative, the result of division is positive (or zero) and the result of modulus is negative (or zero). If only one operand is negative, then the value of the result is machine-dependent for both operators. The sign is also machine-dependent for modulus; the sign is negative (or zero) for division:

如果两个操作数为正,除法(/)和求模(%)操作的结果也是正数(或零);如果两个操作数都是负数,除法操作的结果为正数(或零),而求模操作的结果则为负数(或零);如果只有一个操作数为负数,这两种操作的结果取决于机器;求模结果的符号也取决于机器,而除法操作的值则是负数(或零):

     21 % 6;   //  ok: result is 3
     21 % 7;   //  ok: result is 0
     -21 % -8; //  ok: result is -5
     21 % -5;  //  machine-dependent: result is 1 or -4
     21 / 6;   //  ok: result is 3
     21 / 7;   //  ok: result is 3
     -21 / -8; //  ok: result is 2
     21 / -5;  //  machine-dependent: result -4 or -5

When only one operand is negative, the sign and value of the result for the modulus operator can follow either the sign of the numerator or of the denominator. On a machine where modulus follows the sign of the numerator then the value of division truncates toward zero. If modulus matches the sign of the denominator, then the result of division truncates toward minus infinity.

当只有一个操作数为负数时,求模操作结果值的符号可依据分子(被除数)或分母(除数)的符号而定。如果求模的结果随分子的符号,则除出来的值向零一侧取整;如果求模与分母的符号匹配,则除出来的值向负无穷一侧取整。

Exercises Section 5.1

Exercise 5.1:

Parenthesize the following expression to indicate how it is evaluated. Test your answer by compiling the expression and printing its result.

在下列表达式中,加入适当的圆括号以标明其计算顺序。编译该表达式并输出其值,从而检查你的回答是否正确。

     12 / 3 * 4 + 5 * 15 + 24 % 4 / 2
Exercise 5.2:

Determine the result of the following expressions and indicate which results, if any, are machine-dependent.

计算下列表达式的值,并指出哪些结果值依赖于机器?

     -30 * 3 + 21 / 5
     -30 + 3 * 21 / 5
     30 / 3 * 21 % 5
     -30 / 3 * 21 % 4

Exercise 5.3:

Write an expression to determine whether an int value is even or odd.

编写一个表达式判断一个 int 型数值是偶数还是奇数。

Exercise 5.4:

Define the term overflow. Show three expressions that will overflow.

定义术语“溢出”的含义,并给出导致溢出的三个表达式。


Team LiB
Previous Section Next Section