c - C中的三元运算符?
问题描述
为什么输出显示为 3?这背后的概念是什么?
#include <stdio.h>
int main()
{
int a = 5, b = 4, c;
c = a > b ? 1, 2, 3 : 2, 5, 6;
printf("%d\n", c);
return 0;
}
解决方案
包含三元运算符的代码行错综复杂且耐人寻味。它的解释方式也有微妙但至关重要的不对称性,当它按照问题所示编写时,这些不对称性远非明显。让我们考虑如下原始代码的一个小变体,它同时使用三元运算符的“真”和“假”部分(在两个单独的语句中——尽管我可以创建一个函数并将参数传递给它):
#include <stdio.h>
int main(void)
{
int a = 5, b = 4, c;
c = a > b ? 1, 2, 3 : 2, 5, 6;
printf("a = %d, b = %d, c = %d\n", a, b, c);
a = b - 1;
c = a > b ? 1, 2, 3 : 2, 5, 6;
printf("a = %d, b = %d, c = %d\n", a, b, c);
return 0;
}
该程序的输出是:
a = 5, b = 4, c = 3
a = 3, b = 4, c = 2
这里发生了什么?
请记住,逗号运算符的优先级甚至低于赋值运算符,因此您可以根据需要编写如下代码:
if (a > b)
c = 2, d = 3, e = 6;
并且在语句的主体中有三个赋值if
。这不会被视为一般用途的好代码,但该技术在宏中可能很有用 - 偶尔它可以在宏中有用。
让我们添加一些括号——编译器解释代码时的正确括号集:
c = a > b ? 1, 2, 3 : 2 , 5, 6;
(c = (a > b) ? (1, 2, 3) : 2), 5, 6;
条件a > b
控制是否评估1, 2, 3
或2
,并将结果分配给c
。的结果1, 2, 3
是3
,所以如果a > b
,分配的值是3
(如问题),如果a <= b
,分配的值是2
。The5
和 the6
被评估为副作用 - 但没有副作用,因此它们被有效地丢弃。
三元运算符的对和:
之间的代码有分组作用,不会出现在 之后。?
:
:
请注意,要编译此代码,我必须放弃我的默认编译器选项。使用问题中的代码和我正常的默认编译器选项,我得到(源代码在top67.c
):
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
> top67.c -o top67
top67.c:3:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
int main()
^~~~
top67.c: In function ‘main’:
top67.c:6:18: error: left-hand operand of comma expression has no effect [-Werror=unused-value]
c = a > b ? 1, 2, 3 : 2, 5, 6;
^
top67.c:6:21: error: left-hand operand of comma expression has no effect [-Werror=unused-value]
c = a > b ? 1, 2, 3 : 2, 5, 6;
^
top67.c:6:28: error: right-hand operand of comma expression has no effect [-Werror=unused-value]
c = a > b ? 1, 2, 3 : 2, 5, 6;
^
top67.c:6:31: error: right-hand operand of comma expression has no effect [-Werror=unused-value]
c = a > b ? 1, 2, 3 : 2, 5, 6;
^
cc1: all warnings being treated as errors
$
我会从这个答案中显示的代码中得到更多错误。您应该使用类似的选项进行编译以避免您自己的代码出现问题。
推荐阅读
- r - 比较两个下拉列表中的 CSV 文件 Rshiny
- python - 使用 Python 解析嵌套 JSON:TypeError:列表索引必须是整数,而不是 str
- azure - Azure for Students:意外的 SQL 数据库成本迅速耗尽积分
- wordpress - 登录前隐藏特定产品价格 - woocommerce
- python - 我可以在写入单元格的公式中添加一个字符吗?
- powershell - 如何在 PowerShell 中从 Chrome 获取 URL
- c++ - Vulkan hpp 如何正确处理全局范围内唯一句柄的删除?
- swift - MTKView 刷新问题
- python - 如何使用 Python 组合来自不同数组的 JSON 对象
- qt - 如何在不重新制作所有目标的情况下使用 qmake 添加自定义构建步骤?