三元运算符未生成错误
Ternary Operator Not Generating Error
我熟悉三元运算符已经有一段时间了,并且已经在几种不同的语言中使用过它。我对操作符的理解是:
condition ? expr1 : expr2
但是,在c++中,以下代码是合法的:
int i = 45;
(i > 0) ? i-- : 1;
实际上,你不是在写1;
或i - 1;
吗?这是一个完整的语句吗?我理解代码的意图是减少i
,如果它大于0,但是我认为代码会生成一个编译器错误,因为它只是一个表达式,而不是一个完整的语句。我期望这样的代码:
int i = 45;
i = (i > 0) ? i - 1 : i;
这叫做表达式语句。表达式被求值,其值被丢弃。
42;
,尽管它什么也不做。只有表达式中的副作用(如i--
、赋值等)才有效果。
实际上,我们使用的许多语句都是表达式语句:赋值、函数调用等:
a = 42;
foo();
这是一个有效的表达式。您可能已经收到警告,因为您没有保存表达式的结果,但是您有i--
语句确实有影响。
在c++中,像1
这样的表达式是完全有效的语句,没有副作用。你完全可以这样写:
void f() {
1;
}
事实上,这也是正确的。
void f() {
;;;;
}
文字语句计算其参数,但不做任何其他操作。系统认为1;
和func();
一样。唯一的区别是,虽然func();
在逻辑上有一些副作用,但1;
没有,所以它最终是无操作的。三元操作符的运算方式类似于if语句,因此只有在操作数为真时才计算第二种形式。因此:
(i > 0) ? i-- : 1;
如果i大于0,则计算第二种形式。当它被求值时,它带来了它的副作用,即i减少1。否则,计算第三种形式,它什么也不做。虽然这段代码可以工作,但它的可读性并不高,所以虽然它是很好的玩具代码,但真正的if语句对于这种情况是理想的。出于同样的原因,这一行将具有相同的效果,但会因为同样不可读而皱眉。
((i > 0) && (i--)) || 1;
假设您没有覆盖布尔运算符,此代码将短路并表现为三元运算符。如果i不大于0,则&&不需要计算自&&之后的第二个操作数是假的,但必须,因为它可能是真的。反之,如果i大于0,则&&需要计算,但是||已经知道它是真的
实际上,你不是在写1吗?或I - 1;
No: i--
和i - 1
不一样。在第一种情况下,修改i
的值。对于第二种情况,它不是。
如果i
小于或等于零,那么你是正确的,结果'代码'将是1
。然而,编译器会意识到这不是一个有用的东西,所以它应该生成相当于:
if( i > 0 ) i--;
一些人(包括我自己)会认为以这种方式使用三元操作符是糟糕的风格。只是为了好玩,有人可能会用另一种方式来写它,这种方式也不太好(也更有可能生成编译器警告):
i > 0 && i--;
最后,风格是个人偏好的问题。在大多数情况下,编译器将决定将代码转换为汇编的最佳方式。因此,您应该自己编写清晰而简洁的代码。
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在气泡排序程序中未声明错误功能
- 尝试从C++访问 UWP 的电子邮件邮件类会导致"REGDB_E_CLASSNOTREG类未注册"错误
- SFML 库 - 在 MinGW 构建期间未找到错误
- 尝试运行 wasm 函数时出现模块未定义错误
- 在此范围内未声明错误"Clreol"
- c++中数组的未定义错误
- 基类未定义.错误 C2504
- 在Visual Studio中更新Qt翻译(.ts文件)时出现未指定错误
- 获取线函数未定义错误。无法在字符串中保存可验证的内容
- Rcpp 包创建符号未找到错误
- 如何修复 Typedef 变量未识别错误 C++ (Visual Studio 2017)
- C++单元测试项目 LoadLibrary 失败,出现"序号未找到"错误
- 对于我的 ComplexNumber 中的某些方法,我得到了一个奇怪的未定义错误引用.cpp,不过我对模板很陌生
- 关于Visual Studio 2017中未发现错误的精致询问
- 在.c文件接收函数中使用Linux中的MSGGET创建消息队列未实现错误
- 数据库未打开错误QT C
- 如何在 linux ElementaryOS 中修复 Genymotion,未找到错误"CXXABI_1.3.8"
- 类类型重定义和基类未定义错误
- "inet_ntoa"未声明错误