三元运算符是 if-else 的简洁写法,适合简单的二选一赋值场景,一行搞定。它是 C++ 里唯一一个需要三个操作数的运算符,因此得名"三元"。
4.3
三元运算符是 if-else 的简洁写法,适合简单的二选一赋值场景,一行搞定。
关键要理解的一点是:条件 ? 值1 : 值2 这一整块本身就是一个表达式,它会计算出一个值(值1或值2),这个值可以直接赋给变量、直接输出,或者作为另一个表达式的一部分——这和 if-else 是"语句"(只能执行动作,不能作为值使用)有本质区别。
| 1 | int a = 10, b = 20; |
| 2 | |
| 3 | int maxVal = (a > b) ? a : b; // maxVal = 20 |
| 4 | cout << "较大值是:" << maxVal << endl; |
| 5 | |
| 6 | // 等价的 if-else 写法(更长) |
| 7 | int maxVal2; |
| 8 | if (a > b) maxVal2 = a; |
| 9 | else maxVal2 = b; |
这里 maxVal 那一行给条件部分加了括号——(a > b)。根据 4.1 节学过的优先级,比较运算符本来就比赋值运算符先算,所以这个括号并不是语法强制要求的,去掉也完全能编译通过。加上它纯粹是为了让"这一段是条件"这件事看得更清楚,属于个人风格选择。
正因为三元运算符是一个"表达式"而不是"语句",它还可以直接嵌在 cout 里,不需要先存进一个变量:
| 1 | int score = 78; |
| 2 | cout << (score >= 60 ? "及格" : "不及格") << endl; |
maxVal 例子里"括号只是为了好看"不同,这次 (score >= 60 ? "及格" : "不及格") 外面的括号不能去掉。原因是 << 的优先级比 ?: 高,如果直接写成 cout << score >= 60 ? "及格" : "不及格" << endl;,编译器会先算 cout << score,再拿这个结果去判断 >= 60,逻辑完全乱套,通常会直接编译报错。所以三元运算符写在 cout 里时,一定要把整个表达式 条件 ? 值1 : 值2 用括号整体括起来。三元运算符的"值"部分本身还可以再嵌一层三元运算符,用来表达多重条件——但这已经开始牺牲可读性了,仅作了解:
| 1 | int score = 78; |
| 2 | string grade = score >= 90 ? "优秀" : |
| 3 | score >= 75 ? "良好" : |
| 4 | score >= 60 ? "及格" : "不及格"; |
| 5 | // 等价于 4.2 节的 if-else if-else 链,但可读性明显更差 |
if-else if-else 逻辑完全等价,但阅读起来明显吃力得多——每多嵌一层,理解难度都会显著上升。这就是为什么三元运算符只推荐用于简单的二选一场景,一旦涉及三个以上的分支,if-else if-else 或 switch 才是更合适的选择。把本节内容汇总成几条最容易踩坑的规则:
if-else if-else 几乎总能写得更清楚。三元运算符的价值在于"简洁",一旦开始嵌套,这个优势就荡然无存了。(条件 ? 值1 : 值2) 加括号的习惯,尤其是像 cout << (...) 这样嵌入更大表达式的场景。int 一个是 double(此时 int 会被隐式转换为 double,结果的类型是 double,见 2.2 节隐式转换),这有时会产生不易察觉的精度变化。如果两个分支类型差异较大(比如一个是数字一个是字符串),可能直接编译报错。