6-2 算术运算符

一元算术运算符

存在两种一元算术运算符:加号(+)和减号(-)。需要提醒的是,一元运算符是仅接受一个操作数的运算符。

Operator Symbol Form Operation
Unary plus + +x Value of x
Unary minus - -x Negation of x

一元减unary minus运算符返回操作数乘以-1的结果。换言之,若x=5,则-x等于-5。

一元加unary plus运算符返回操作数的原始值。换言之,+5等于5,+x等于x。通常无需使用此运算符,因其存在冗余性。该运算符主要为与一元减运算符保持对称性而添加。

为提高可读性,这两个运算符都应紧接在操作数之前(例如 -x,而非 - x)。

请勿将一元减运算符与二元减法运算符混淆,它们使用相同的符号。例如在表达式 x = 5 - -3; 中,第一个减号是二元减法运算符,第二个是一元减运算符。


二进制算术运算符

共有5个二进制算术运算符。二进制运算符是指同时接受左操作数和右操作数的运算符。

Operator Symbol Form Operation
Addition + x + y x plus y
Subtraction - x - y x minus y
Multiplication * x * y x multiplied by y
Division / x / y x divided by y
Remainder % x % y The remainder of x divided by y

加法、减法和乘法运算符与现实生活中的用法完全一致,没有任何特殊限制。

除法和取余运算需要额外说明。除法将在下文讨论,取余运算则留待下一课讲解。


整数与浮点数除法

最简便的理解方式是将除法运算符视为具有两种不同的“模式”。

当任一(或两者)操作数为浮点数Floating point division时,除法运算符执行浮点数除法。浮点除法返回浮点数值,且保留小数部分。例如:7.0 / 4 = 1.75,7 / 4.0 = 1.75,7.0 / 4.0 = 1.75。与所有浮点运算相同,此过程中可能产生舍入误差。

若两个操作数均为整数,则除法运算符执行整数除法。整数除法Integer division舍弃小数部分并返回整数值。例如 7 / 4 = 1(因舍弃小数部分),同理 -7 / 4 = -1(因舍弃小数部分)。


使用static_cast<>对整数进行浮点除法

这引发了一个问题——如果我们有两个整数,想要进行除法运算而不丢失小数部分,该如何实现?

第4.12节——类型转换与static_cast介绍中,我们展示了如何使用static_cast<>运算符将字符转换为整数,使其以整数形式而非字符形式输出。

同理,我们可使用static_cast<>将整数转换为浮点数,从而实现浮点除法而非整数除法。请看以下代码:

#include <iostream>

int main()
{
    constexpr int x{ 7 };
    constexpr int y{ 4 };

    std::cout << "int / int = " << x / y << '\n';
    std::cout << "double / int = " << static_cast<double>(x) / y << '\n';
    std::cout << "int / double = " << x / static_cast<double>(y) << '\n';
    std::cout << "double / double = " << static_cast<double>(x) / static_cast<double>(y) << '\n';

    return 0;
}

这产生了以下结果:

image

上述内容说明,如果任一操作数是浮点数,则结果将是浮点除法,而非整数除法。


除以 0 和 0.0

当除数为 0 时进行整数除法会导致未定义行为,因为结果在数学上是未定义的!

#include <iostream>

int main()
{
	constexpr int apples { 12 };
	std::cout << "You have " << apples << " apples. Enter how many people to divide them between: ";
	int x {};
	std::cin >> x;

	std::cout << "Each person gets " << apples / x << " whole apples.\n"; // apples and x are int, so this is integer division

	return 0;
}

image
image

若运行上述程序并输入0,程序很可能崩溃。尽管尝试,这不会损坏您的计算机。

除以浮点数0.0的结果取决于具体实现(即行为由编译器/架构决定)。在支持IEEE754浮点格式的架构上,结果将为NaN或Inf;在其他架构上,结果很可能导致未定义行为。

相关内容
我们在第4.8节——浮点数中讨论了NaN和Inf。

你可以通过运行以下程序并输入0或0.0来查看程序的运行效果:

#include <iostream>

int main()
{
	constexpr int apples { 12 };
	std::cout << "You have " << apples << " apples. Enter how many servings of apples you want: ";

	double d {};
	std::cin >> d;

	std::cout << "Each serving is " << apples / d << " apples.\n"; // d is double, so this is floating point division

	return 0;
}

image
image


算术赋值运算符

Operator Symbol Form Operation
Addition assignment += x += y Add y to x
Subtraction assignment -= x -= y Subtract y from x
Multiplication assignment *= x *= y Multiply x by y
Division assignment /= x /= y Divide x by y
Remainder assignment %= x %= y Put the remainder of x / y in x

到目前为止,当你需要向变量添加4时,你很可能这样操作:

x = x + 4; // add 4 to existing value of x

这段代码能运行,但略显笨拙,且需要两个运算符才能执行(加法运算符和赋值运算符)。

由于像 x = x + 4 这样的语句非常常见,C++ 为方便起见提供了五个算术赋值运算符。无需编写 x = x + 4,可改写为 x += 4;无需编写 x = x * y,可改写为 x *= y。

因此,上述代码可简化为:

x += 4; // add 4 to existing value of x

修改运算符与非修改运算符

能够修改其操作数值的运算符通常被称为修改运算符modifying operator。在C++中,大多数运算符属于非修改运算符——它们仅使用操作数进行计算并返回结果值。然而,有两类内置运算符既会修改左操作数(同时返回结果值):

  • 赋值运算符,包括标准赋值运算符(=)、算术赋值运算符(+=、-=、*=、/=、%=)以及位运算赋值运算符(<<=、>>=、&=、|=、^=)。
  • 增量与减量运算符(分别是++和--)。这些将在第6.4节——增量/减量运算符及其副作用中讨论。

列表中未包含的运算符包括==、!=、<=和>=,因其为非修改型关系(比较)运算符(=表示“等于”)。这些将在第6.7节——关系运算符与浮点数比较中讨论。

对于进阶读者
重载运算符可被重新定义为与内置运算符不同的行为,这可能包括修改左操作数(即使内置版本不修改)或反之。例如用于输出的重载operator<<运算符会修改其左操作数(输出流对象)。

posted @ 2026-02-19 08:01  游翔  阅读(2)  评论(0)    收藏  举报