许多人写 C++ 程序时,常把条件运算符 ?: 看做代替 if-else 的绝佳方式,我也不例外。在解 P1067 时,我便用过 ?: 来判断系数的正负:
cout<<a<0?'-':'+';
看到这里,相信细心的大家已经发现,这句代码的 a<0?'-':'+' 必须要加上括号,否则会与 cout 的 << 运算符混淆!然而,当时的我却没有意识到这一点,硬是把这段代码打在了 Dev-C++ 上,虽然这个程序的输出大错特错,但至少成功通过了编译。真正让我意想不到的是,评测机的编译竟然没过!我看了看编译信息,编译的出错恰好归咎于我对 ?: 的错误使用:
错误:no match for ‘operator<’ (operand types are ‘std::basic_ostream<char>’ and ‘int’)
16 | cout<<a<0?'-':'+';
这样的评测结果,正好给我来了当头一棒——我不能再让 cout 也参与到 ?: 运算中去了。但此时,我又有了个疑问:为什么这段代码用评测机编译,就不能通过,而却“侥幸”通过了 Dev-C++ 的编译?这难道是因为操作数类型的问题?我尝试了一下。对于 cout<<a?b:c 这样的同种语句格式,不同编译器获得了这样的编译结果:
?: 表达式第一个操作数的类型 | Dev-C++ 编译器 | 洛谷评测机 |
|---|
int | 成功 | 成功 |
| 含关系运算符的条件表达式 | 成功或失败无法确定∗ | 失败 |
∗注:cout<<a<0?'-':'+' 在 Dev-C++ 上可以通过编译,cout<<0<1?2:3 则会失败。
看到了如此“变化多端”的结果,我更疑惑不解了:为什么用同一种运算符写代码,仅仅改变操作数,不同编译器的结果会不同,甚至同一个编译器也有事先无法确定的结果?