C++ 运算符

C++C++Beginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何在 C++ 中使用运算符。你将学习如何使用算术运算符、关系运算符、逻辑运算符和位运算符。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL cpp(("C++")) -.-> cpp/BasicsGroup(["Basics"]) cpp(("C++")) -.-> cpp/ControlFlowGroup(["Control Flow"]) cpp(("C++")) -.-> cpp/StandardLibraryGroup(["Standard Library"]) cpp/BasicsGroup -.-> cpp/variables("Variables") cpp/BasicsGroup -.-> cpp/data_types("Data Types") cpp/BasicsGroup -.-> cpp/operators("Operators") cpp/BasicsGroup -.-> cpp/booleans("Booleans") cpp/ControlFlowGroup -.-> cpp/conditions("Conditions") cpp/StandardLibraryGroup -.-> cpp/math("Math") subgraph Lab Skills cpp/variables -.-> lab-178538{{"C++ 运算符"}} cpp/data_types -.-> lab-178538{{"C++ 运算符"}} cpp/operators -.-> lab-178538{{"C++ 运算符"}} cpp/booleans -.-> lab-178538{{"C++ 运算符"}} cpp/conditions -.-> lab-178538{{"C++ 运算符"}} cpp/math -.-> lab-178538{{"C++ 运算符"}} end

内容预览

对于基本的数值和逻辑数据,我们使用运算符对它们进行操作。与其他语言一样,C++ 对运算符提供了全面的支持。现在开始学习它们。

  • 算术运算
  • 混合类型运算
  • 复合赋值运算符
  • 类型转换
  • 关系和逻辑运算符

算术运算

C++ 支持以下用于数字的算术运算符:

运算符 描述 用法 示例
* 乘法 expr1 * expr2 2 _ 3 → 6; 3.3 _ 1.0 → 3.3
/ 除法 expr1 / expr2 1 / 2 → 0; 1.0 / 2.0 → 0.5
% 取余(模运算) expr1 % expr2 5 % 2 → 1; -5 % 2 → -1
+ 加法 expr1 + expr2 1 + 2 → 3; 1.1 + 2.2 → 3.3
- 减法 expr1 - expr2 1 - 2 → -1; 1.1 - 2.2 → -1.1

以上所有运算符都是二元运算符,它们需要两个操作数。乘法、除法和取余运算的优先级高于加法和减法。

需要注意的是,int/int 的结果是 int 类型,结果会被截断,例如 1/2 → 0(而不是 0.5)。

混合类型运算

如果算术运算的两个操作数属于相同类型,则运算在该类型下进行,结果也属于该类型。然而,如果两个操作数属于不同类型,编译器会将较小类型的值提升为较大类型(称为隐式类型转换),然后在较大类型下进行运算。

类型 示例 运算
int 2 + 3 int 2 + int 3 → int 5
double 2.2 + 3.3 double 2.2 + double 3.3 → double 5.5
混合 2 + 3.3 int 2 + double 3.3 → double 2.0 + double 3.3 → double 5.3
int 1 / 2 int 1 / int 2 → int 0
double 1.0 / 2.0 double 1.0 / double 2.0 → double 0.5
混合 1 / 2.0 int 1 / double 2.0 → double 1.0 + double 2.0 → double 0.5

例如

/* 测试混合类型算术运算 */
#include <iostream>
#include <iomanip>   // 用于格式化浮点数
using namespace std;

int main() {
   int i1 = 2, i2 = 4;
   double d1 = 2.5, d2 = 5.0;

   // 以固定格式显示浮点数,保留1位小数
   cout<<fixed<<setprecision(1);

   cout << i1 << " + " << i2 << " = " << i1+i2 << endl;  // 6
   cout << d1 << " + " << d2 << " = " << d1+d2 << endl;  // 7.5
   cout << i1 << " + " << d2 << " = " << i1+d2 << endl;  // 7.0  <==

   cout << i1 << " - " << i2 << " = " << i1-i2 << endl;  // -2
   cout << d1 << " - " << d2 << " = " << d1-d2 << endl;  // -2.5
   cout << i1 << " - " << d2 << " = " << i1-d2 << endl;  // -3.0 <==

   cout << i1 << " * " << i2 << " = " << i1*i2 << endl;  // 8
   cout << d1 << " * " << d2 << " = " << d1*d2 << endl;  // 12.5
   cout << i1 << " * " << d2 << " = " << i1*d2 << endl;  // 10.0 <==

   cout << i1 << " / " << i2 << " = " << i1/i2 << endl;  // 0    <==
   cout << d1 << " / " << d2 << " = " << d1/d2 << endl;  // 0.5
   cout << i1 << " / " << d2 << " = " << i1/d2 << endl;  // 0.4  <==
   return 0;
}

输出:

2 + 4 = 6
2.5 + 5.0 = 7.5
2 + 5.0 = 7.0
2 - 4 = -2
2.5 - 5.0 = -2.5
2 - 5.0 = -3.0
2 * 4 = 8
2.5 * 5.0 = 12.5
2 * 5.0 = 10.0
2 / 4 = 0
2.5 / 5.0 = 0.5
图片描述

溢出 / 下溢

// int 的范围是 [-2147483648, 2147483647]
   int i1 = 2147483647;      // int 最大值
   cout << i1 + 1 << endl;   // -2147483648 (溢出)
   cout << i1 * i1 << endl;  // 1

   int i2 = -2147483648;     // int 最小值
   cout << i2 - 1 << endl;   // 2147483647 (下溢)
   cout << i2 * i2 << endl;  // 0

在算术运算中,如果结果超出其范围,值会回绕。C++ 运行时不会发出错误/警告信息,但会产生错误的结果。需要注意的是,检查溢出/下溢是程序员的责任

复合赋值运算符

C++ 还提供了以下所谓的复合赋值运算符

运算符 用法 描述 示例
= var = expr 将右侧表达式的值赋给左侧变量 x = 5;
+= var += expr 等同于 var = var + expr x += 5; 等同于 x = x + 5
-= var -= expr 等同于 var = var - expr x -= 5; 等同于 x = x - 5
*= var *= *expr* 等同于 var = var * expr x _= 5; 等同于 x = x _ 5
/= var /= expr 等同于 var = var / expr x /= 5; 等同于 x = x / 5
%= var %= expr 等同于 var = var % expr x %= 5; 等同于 x = x % 5
++ ++x 前自增 y=++x; 等同于 x=x+1; y=x
++ x++ 后自增 y=x++; 等同于 oldX=x; x=x+1; y=oldX
-- --x 前自减 y=--x; 等同于 x=x-1; y=x
-- x-- 后自减 y=x--; 等同于 oldX=x; x=x-1; y=oldX
x = 5;
cout << x++ << endl;  // 保存 x (5); 自增 x (=6); 输出旧值 x (5).
x = 5;
cout << ++x << endl;  // 自增 x (=6); 输出 x (6).

隐式类型转换 vs. 显式类型转换

当你将一个基本(内置)类型的值赋给另一个基本类型的变量时,如果这两种类型兼容,C++ 会自动将该值转换为接收类型。例如:

  • 如果你将一个 int 值赋给一个 double 变量,编译器会自动将 int 值转换为 double 类型(例如,从 1 转换为 1.0),然后将其赋给 double 变量。
  • 如果你将一个 double 值赋给一个 int 变量,编译器会自动将 double 值转换为 int 类型(例如,从 1.2 转换为 1),然后将其赋给 int 变量。小数部分会被截断并丢失。某些编译器会发出“可能丢失精度”的警告/错误;而其他编译器则不会。
 int i;
 double d;

 i = 3;
 d = i;    // 将 int 值赋给 double
 cout << "d = " << d << endl;  // 3.0

 d = 5.5;
 i = d;    // 将 double 值赋给 int
 cout << "i = " << i << endl;  // 5 (截断,无警告!)

你可以通过所谓的一元类型转换运算符显式执行类型转换,形式为 (新类型) 操作数新类型 (操作数)。类型转换运算符接受一个特定类型的操作数,并返回新类型的等效值。请注意,这是一个生成结果值的操作,类似于加法操作,尽管加法涉及两个操作数。例如:

cout << (double)5 << endl;  // int 5 → double 5.0
cout << (int)5.5 << endl;   // double 5.5 → int 5

double aDouble = 5.6;
int anInt = (int)aDouble; // 返回 5 并赋给 anInt。aDouble 不会改变!

// C++ 也支持函数式类型转换。
cout << double(5) << endl;     // 5.0
cout << int(5.5) << endl;      // 5
cout << int(aDouble) << endl;  // 5

关系和逻辑运算符

在决定采取何种操作之前,你经常需要比较两个值。C++ 提供了六种比较运算符(或关系运算符):

运算符 描述 用法 示例 (x=5, y=8)
== 等于 expr1 == expr2 (x == y) → false
!= 不等于 expr1 != expr2 (x != y) → true
> 大于 expr1 > expr2 (x > y) → false
>= 大于或等于 expr1 >= expr2 (x >= 5) → true
< 小于 expr1 < expr2 (y < 8) → false
<= 小于或等于 expr1 >= expr2 (y <= 8) → true
&& 逻辑 AND expr1 && expr2 --------
|| 逻辑 OR expr1 || expr2 --------
! 逻辑 NOT !expr --------
^ 逻辑 XOR expr1 ^ expr2 --------

真值表如下:

AND (&&) true false
true true false
false false false
OR (||) true false
true true true
false true false
NOT (!) true false
false true
XOR (^) true false
true false true
false true false
// 如果 x 在 0 到 100 之间(包括 0 和 100),返回 true
(x >= 0) && (x <= 100)
// 错误用法:0 <= x <= 100

// 如果 x 在 0 到 100 之外(包括 0 和 100),返回 true
(x < 0) || (x > 100)   // 或者
!((x >= 0) && (x <= 100))

// 如果 year 是闰年,返回 true
// 闰年的条件是:能被 4 整除但不能被 100 整除,或者能被 400 整除。
((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)

总结

这一部分相对简单,你应该将它们与前面的内容联系起来。不需要死记硬背,而是要在脑海中理解它们的逻辑。