【问题标题】:set 2 values in a ternary operation - C在三元运算中设置 2 个值 - C
【发布时间】:2017-02-26 22:36:52
【问题描述】:

我在使用 C 中的三元运算符设置两个整数时遇到问题。我似乎找不到答案,因为大多数问题都与多个三元条件有关。

然而,我想检查一个条件并相应地设置 2 个值。

即:

if ( i == 5 ) {
    x = foo;
    y = foo + 1;
} else {
    x = bar;
    y = bar + 1;
}

到目前为止,我尝试了以下方法,但似乎不起作用。

x, y = ( i == 5 ) ? foo, foo + 1 : bar, bar + 1;

是否可以在检查 1 个条件后以三进制设置两个值?

谢谢,

【问题讨论】:

  • 为什么不坚持使用 if 语句 - 可读、可维护等。三元运算符只是语法糖。保持代码简单易懂。更容易调试。更容易修复。 ....
  • @Olaf - 这在 Python 中是个好主意吗?
  • 不,C 中不支持元组。如果您的示例是真实代码,正确的答案是使用三元运算符设置x,然后设置y=x+1。跨度>
  • 在 python 中,通常的做法是返回多个参数。所以我会说是的。
  • @EdHeal:不是这个(当然也不是相同的语法)。但是,是的,您可以这样使用三元运算符。尽可能多地将钢琴钉在膝盖上:-)

标签: c if-statement ternary-operator


【解决方案1】:

实现设置两个值目标的各种方法:

当然第一个是干净易读的。

if ( i == 5 ) {
    x = foo;
    y = foo + 1;
} else {
    x = bar;
    y = bar + 1;
}

另一种方法是设置一个对象的N 字段并使用C11 复合文字 分配它。这适用于?:,因为代码正在设置一个对象。

  int i = rand(), foo = rand(), bar = rand();
  typedef struct {
    int x;
    int y;
    int z;
  } xyz_T;
  xyz_T xyz = (i == 5) ? 
      (xyz_T ) { .x = foo, .y = foo + 1, .z = 1 } : 
      (xyz_T ) { .x = bar, .y = bar + 1, .z = 2 };

【讨论】:

    【解决方案2】:

    虽然我不建议为此使用单个三元运算,但可以做到。如果这只是一个挑战,这里有一些解决方案:

    y = 1 + (i == 5 ? (x = foo) : (x = bar));
    

    或者:

    y = 1 + (x = i == 5 ? foo : bar);
    

    或更笼统地说:

    (i == 5) ? (x = foo, y = foo + 1) : (x = bar, y = bar + 1);
    

    如您所见,所有这些都有些扭曲,可读性不强。

    如果你能写2条语句,我会推荐:

    x = (i == 5) ? foo : bar;
    y = x + 1;
    

    【讨论】:

    • 谢谢,是的,最后 2 个语句提供了更多的灵活性
    【解决方案3】:

    这是不可能的。与支持分配给数字列表的 python 或 perl 不同,C 不支持这种语法。

    您需要两个单独的三元运算来执行此操作:

    x = (i == 5) ? foo : bar;
    y = (i == 5) ? foo + 1 : bar + 1;
    

    如果您只希望条件运行一次(例如,它是函数调用或其他一些昂贵的操作):

    int result = (i == 5);
    x = result ? foo : bar;
    y = result ? foo + 1 : bar + 1;
    

    编辑:

    如果你想用一些难看的东西,这会起作用:

    x = (i == 5) ? (y = foo + 1, foo) : (y = bar + 1, bar);
    

    通过使用逗号运算符,运算符的左侧被求值(在这种情况下,分配给y)并被丢弃,而右侧成为随后被分配给x 的表达式的值。

    请注意,“if”部分并不严格需要括号,但“else”部分需要括号。

    然而,这是对语言的滥用。最好坚持使用更具可读性的内容。

    【讨论】:

    • 逗号运算符的有趣使用...我的比较简单,但仍然不推荐。
    • @chqrlie 在 OP 的特定情况下,xy 的值是相关的。一般情况下,上述方法将起作用。
    • 我一开始确实利用了这种关系,但你的方法启发了一个更通用的选择:(i == 5) ? (x = foo, y = foo + 1) : (x = bar, y = bar + 1); 一样丑陋,但很容易扩展到任意数量的任务。
    【解决方案4】:

    正如@dbush 所说,你不能在 C 中这样做。在 C++ 中你可以使用各种元组类型,但这超出了问题的范围。

    那为什么不呢?在 Python 和许多较新的语言中,逗号运算符将值(松散地说)捆绑在一起,因此可以将它们视为一个单元。这就是 Python 所做的,以及允许 x,y = 1,2 if a else 3,4 工作的原因。

    然而,在 C 中,逗号运算符分隔 表达式语句,而不是 a,b 评估 a,丢弃结果,评估 b,并提供评估 b 的结果作为逗号的结果。 ab 绝不会一起考虑。

    (C 向导和语言律师:为了 OP 的可读性,我故意省略左值/右值考虑和其他更精细的语义点。是的,你是正确的,完整的答案不应该这样做。:))

    【讨论】:

      【解决方案5】:

      你可以使用一个函数:

      void setAndIncrement(int val, int *x, int *y) {
          *x = val;
          *y = val + 1;
      }
      
      ....
      
      (i == 5) ? setAndIncrement(foo, &x, &y): setAndIncrement(bar, &x, &y);
      

      但这不会使任何事情变得更好或更容易维护。你真的应该坚持使用ifelse。它易于阅读、可维护并且完全按照您应该做的方式进行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-15
        • 2014-12-15
        • 2019-01-21
        • 2018-03-13
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        相关资源
        最近更新 更多