在 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 语句 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在C语言中,if和else if是否在不加花括号的情况下也是一个复合语句

C语言表达式和语句

在C语言中条件语句都有哪些需要注意的事项?

控制语句

c语言中,三木运算符和if语句哪个效率更高一些?

if-else语句中,if和else的配对原则各是啥