在 C++ 中,三元运算符也叫做 “条件运算符” 或 “三目运算符”。它由英文问号(?)和英文冒号(:)组成,需要 3 个操作数共同参与运算,因此称为三元运算符。
如果我们只是想根据一个条件,从两个值中选出一个来赋值或输出,写完整的 if...else 语句会显得有些繁琐,使用三元运算符一行代码就能搞定。
C++ 三元运算符语法
在 C++ 中,三元运算符的执行逻辑非常简单,其实就是 “先判断条件,再二选一”。
语法:
条件 ? 表达式 1 : 表达式 2说明:
问号(?)前面的 “条件” 通常是一个布尔判断表达式,比如 a > b。如果条件为 true,整个三元表达式的结果就是 “表达式 1” 的值;如果条件为 false,结果就是 “表达式 2” 的值。
你可以把它拆成 3 个部分来记:问号前面放判断条件,问号和冒号中间放条件成立时的结果,冒号后面放条件不成立时的结果。这 3 个部分缺一不可,不能像单向 if 语句那样省略不成立时的分支。
C++ 三元运算符示例
下面我们通过几个简单的例子,来看看三元运算符是如何使用的。
示例 1:获取两个数的较大值
#include <iostream>
int main() {
int a = 10;
int b = 20;
int max = a > b ? a : b;
std::cout << max << '\n';
return 0;
}运行结果如下。
20分析:
a > b ? a : b 表示先判断 a > b 是否成立。由于 a 为 10、b 为 20,a > b 返回 false,因此整个三元表达式取冒号后面的 b,最后将 20 赋值给变量 max。
实际上,三元运算符可以看作 if...else 赋值语句的一种简写形式。对于上面这个例子来说,下面 2 种方式是等价的:
// 方式 1(推荐)
int max = a > b ? a : b;
// 方式 2
int max;
if (a > b) {
max = a;
} else {
max = b;
}对比上面两种写法可以看出,原本需要好几行代码的 if...else 赋值逻辑,使用三元运算符一行代码就写完了,更加直观紧凑。
三元运算符后两个位置上不仅能写单个变量或常量,也可以直接写算术表达式。如果需要在选出分支的同时完成数值计算,又应该怎么写呢?请看下面例子。
示例 2:计算满减实付金额
#include <iostream>
int main() {
int price = 120;
// 满 100 减 20
int pay = price >= 100 ? price - 20 : price;
std::cout << "实付金额:" << pay << '\n';
return 0;
}运行结果如下。
实付金额:100分析:
在这个例子中,变量 price 为 120,条件 price >= 100 返回 true,程序计算问号后面的 price - 20 得到 100 并赋给 pay。如果把 price 改为 80,条件返回 false,就会直接取冒号后面的 price,实付金额仍为 80。
需要注意的是,当条件判断完成后,程序只会计算被选中的那一边表达式,另一边表达式不会被执行。下面代码中,变量 pay 的最终值是 90,小伙伴们可以思考一下为什么。
int price = 100;
int pay = price > 100 ? price - 20 : price - 10;由于三元运算符本身就会计算出一个结果值,我们也可以不定义中间变量,直接把它放进 std::cout 语句中输出结果。
示例 3:直接输出判断结果
#include <iostream>
int main() {
int score = 75;
std::cout << (score >= 60 ? "及格" : "不及格") << '\n';
return 0;
}运行结果如下。
及格分析:
这里变量 score 的值为 75,条件 score >= 60 返回 true,小括号内的三元表达式得出字符串 "及格",随后通过 std::cout 直接打印到屏幕上。
细心的小伙伴可能会发现,上面的输出语句使用了一对小括号 () 把整个三元表达式括了起来。这是因为按照运算符优先级规则,输出运算符 << 的优先级比 ? : 更高。
如果省略这对小括号,编译器会先计算左边的 std::cout << score,导致后面的 ? : 无法正常匹配而编译报错:
// 正确方式
std::cout << (score >= 60 ? "及格" : "不及格") << '\n';
// 错误方式
std::cout << score >= 60 ? "及格" : "不及格" << '\n';而当把三元运算符放在赋值语句右边时,因为赋值运算符 = 的优先级比 ? : 更低,所以不加小括号也能正常计算。平时如果不确定优先级,给整个三元表达式加上小括号也是稳妥的做法。
注意 三元运算符冒号(:)两边的表达式类型必须相同,或能通过类型转换统一为同一种类型。如果写成 score >= 60 ? "及格" : 0 这样一边是字符串、另一边是整数,编译时就会直接报错。
三元运算符与 if...else 的区别
既然三元运算符写起来这么简短,那它能不能完全替代 if...else 语句呢?答案是不能。在实际开发中,它们各自有着明确的适用场景:
- 三元运算符:适合简单的 “根据一个条件二选一并得出结果值” 的场景,比如给变量赋初值或直接输出简单结果。
- if...else 语句:适合分支判断条件较多,或者每个分支内部需要执行多条语句的场景。
在语法上,三元运算符也支持嵌套使用,比如把多个分数段的等级判断挤在一行代码里:
// 不推荐
char grade = score >= 90 ? 'A' : (score >= 80 ? 'B' : 'C');上面这行代码虽然能够正常编译运行,但多个问号和冒号连在一起,可读性比较差。一旦遇到多层条件判断,或者分支里需要执行多条语句,我们更推荐使用 if...else if...else 把分支结构清晰地展开,不要为了省几行代码去嵌套三元运算符。
