在 C 中使用 ?: 运算符的复合 if 语句 [重复]
Posted
技术标签:
【中文标题】在 C 中使用 ?: 运算符的复合 if 语句 [重复]【英文标题】:Compound if statement using ?: operator in C [duplicate] 【发布时间】:2014-09-23 17:51:39 【问题描述】:是否可以使用“?”来编写等效的复合“if”语句C中的运算符?我想写一个“if - else if - else”语句,想知道我是否可以使用“?”运算符。
我相信使用“?”的常规语法会像
foo = (bar == 42) ? answerToEverything : useless;
如果我想在一行中使用“?”重写以下语句接线员,我可以这样做吗?怎么样?
if(bar == 42)
foo = answerToEverything;
else if(bar == 23)
foo = bigMike;
else foo = useless;
【问题讨论】:
(bar==42) ? foo = answerToEverything : (bar==23) ? foo = bigMike : foo = useless
我认为嵌套三元运算符有点丑。你所拥有的一切都很好 IMO
我也同意@Ben。您使用条件运算符(通常令人困惑地命名为“三元运算符”)编写它的目标是什么?
你为什么不直接使用switch
声明?
我会说“为什么要重写它?”三元运算符机制在某些情况下很方便,因为它隐藏了您并不真正需要担心的细节,但是在使用它的任何复杂性的情况下使用它太容易导致混乱和错误。拒绝吧!”到三元。
【参考方案1】:
foo =
(bar == 42) ? answerToEverything :
(bar == 23) ? bigMike :
useless;
【讨论】:
@Ben:当我希望foo
为 const 并且我希望包含结果的代码具有空间局部性时,我通常使用它。
@Ben:我还认为其他答案正在严重格式化他们的代码。如果我像他们一样格式化它,我不会使用它。
@Ben:我是三元运算符的粉丝,但嵌套它是一种肯定会在未来迷惑自己并激怒同事的方法!
+1 证明正确的格式很重要。
不这样做的原因是它隐藏了存在的嵌套,您仍然必须“解析”它才能理解它。在您开始查看细节之前,使用嵌套的 if,您的眼睛会为您“解析”结构(如果它的格式正确)。我的意思是,上面看起来很“整洁”,但是,老实说,你真的能看看它并说出它的作用吗?【参考方案2】:
是的,你可以,但它很难看而且很难理解!
我建议使用多行形式,因为它更容易理解:
if (bar == 42)
foo = answerToEverything;
else if (bar == 23)
foo = bigMike;
else
foo = useless;
但是,如果你真的想让你的代码难以阅读:
foo = (bar == 42)
? answerToEverything
: (bar == 23)
? bigMike
: useless;
当然,您可以随意使用空格进行格式化。
【讨论】:
像 sharth 演示的更好的格式使它更漂亮。 IMO 上述格式比 sharth 的更好,因为它实际上揭示了结构,而 sharth 隐藏了它。格式化的目的不是为了看起来漂亮,而是为了使结构清晰。【参考方案3】:是的,您可以这样做,如下所示。
但是,嵌套条件运算符经常被认为是不好的风格。这会损害可读性。
foo = (bar == 42)
? answerToEverything
: ((bar==23) ? bigMike : useless );
【讨论】:
另见接受的答案,它显示了如何获得 both 嵌套条件 和 可读性,至少对于短表达式而言。【参考方案4】:是的。您可以在尾部继续堆叠三元运算符表达式:
foo = (bar == 42) ? answerToEverything : ( (bar==23) ? bigMike : useless);
当然,可读性是最重要的,所以你最好使用 if 语句,或者如果可能的话,最好使用 switch-case 语句:
switch (bar)
case 42: foo = answerToEverything; break;
case 23: foo = bigMike; break;
default: foo = useless;
【讨论】:
我来晚了……嵌套三元语句——这是我见过的最疯狂的语法。感谢您使用switch
声明对此进行解释。嵌套三元组比 switch 快吗?
@Chris22 这最终将取决于您的特定情况以及编译器如何优化它。通常,带有许多case
子句的switch
语句是通过查找表而不是详尽检查来实现的。如果性能在这里真的很重要,请考虑衡量两者之间的差异。
谢谢,我一定会测量两者之间的差异。我问是因为switch
通常比更长的if
语句列表更快,所以我想知道嵌套三元是否“通常”比所有其他三元都快。如果它很长,就不容易阅读(在代码审查期间,我遇到了这种语法,包含 5+ 个嵌套条件),所以我想知道为什么编码器会使用它。【参考方案5】:
您已经收到了几个正确的答案,但到目前为止发布的所有答案都包含过多的()
。 (有趣的是,他们的作者大胆地丢弃了整个嵌套的?:
运算符周围的()
,但羞怯地坚持在==
比较周围保留()
。我自己,我对丢弃前者而不是后者。)无论如何,由于我们已经在尝试在优先级和关联性风险方面处于领先地位,这是我的版本
foo =
bar == 42 ? answerToEverything :
bar == 23 ? bigMike :
useless;
通过?:
运算符实现它的一个[小] 问题是,您通常无法看到在逐步调试器中采用了哪条路径。大多数(如果不是全部)调试器会将上述操作视为原子操作并一步执行。 (更准确地说,大多数编译器 会生成将其视为原子操作的调试信息。)使用 if-ladder 方法,您将明确看到采用了什么路径。
【讨论】:
示例代码似乎与@sharth 之前的漂亮答案相同,但删除了条件周围的括号。括号对于人类的视觉分组可能很有价值,即使编译器不需要它们。我个人觉得 sharth 的版本更具可读性。 @AndyThomas:我个人赞成这个答案。加上第二段,我的支持更加自信。 @Andy Thomas:@sharth 答案正是我窃取原始代码版本的地方。请注意,我无意声称我的版本“更好”或更“正确”。我只是想另外说明一个事实,即比较周围的()
是多余的。但是,在这种特定情况下(即?:
运算符的比较部分),我个人确实认为过多的()
很烦人,并且没有它(只要格式正确),代码阅读起来会更好。 【参考方案6】:
如果我理解你的问题,那么 yes 使用嵌套三元组,例如
foo = (bar == 42) ? answerToEverything : ((bar == 23) ? bigMike : useless);
请注意,我不建议您使用嵌套三元 - 它很难阅读。
【讨论】:
【参考方案7】:你可以使用复合 ?: 语句。
如前面的代码可能如下:
(bar == 42) ? (foo = answerToEverything): ((bar == 23) ? (foo = bigMike) : (foo = useless));
【讨论】:
【参考方案8】:我相信这应该可以满足您的需求。它本质上是结合了两个复合 if 语句。只有当第一个评估为 false 时,第二个才会被评估。
foo = (bar == 42) ? "answerToEverything" : ((bar == 23) ? "bigMike" : "useless");
我在一个在线编译器中运行它,并将 foo 设为字符串并将 bar 设为 int,它的行为符合预期。
【讨论】:
以上是关于在 C 中使用 ?: 运算符的复合 if 语句 [重复]的主要内容,如果未能解决你的问题,请参考以下文章