【问题标题】:Applying increment to ternary operator in C在C中将增量应用于三元运算符
【发布时间】:2011-10-13 16:26:13
【问题描述】:

我认为三元运算符根据条件返回: 左侧或右侧的值。为什么下面这段代码会打印 1?

#include <stdio.h>

int main(int argc, char const *argv[]) {
  int c = 0;
  (c?c:0)++;
  printf("%i", c);
  return 0;
}

【问题讨论】:

  • 当这个0++; 被执行时,你期望会发生什么?我什至无法想象这会编译。
  • 逻辑还是有缺陷的,这里没有打印三元运算符的值
  • 但是 (c?0:c)++ 没有编译,疯了
  • 使用 GCC 4.5.0:In function ‘main’: 5:2: error: lvalue required as increment operand 使用 gcc -S code.cpp 编译此代码时返回什么?
  • 无论出于何种原因,它只发生在0... 至少在我的 gcc 4.4.3 上,对于其他一切它不允许它编译。看起来像一个错误。

标签: c increment ternary-operator


【解决方案1】:

您似乎有编译器错误,或者可能是语言扩展,因为这不是有效的 C。您需要一个左值才能应用 ++ 运算符,而(c?c:0) 不是左值。

【讨论】:

  • 如果c在那一行之前是0,为什么它会增加???即将发生未定义的行为?
  • 会是一个很好的评论,糟糕的措辞......因为它是一个编译器错误,它可能会根据(c?c:0) == c进行“优化”
  • @unkulunkulu :C99 标准确实明确指出:“如果尝试修改条件运算符的结果或在下一个序列点之后访问它,则行为未定义。”跨度>
  • @Sander:不,这不是多余的。我认为实际上可以在不违反约束的情况下做到这一点,比如这个或类似的东西:struct mystruct { int x; int a[2]; } r, s; (1 ? r : s).a[1] = 42;。参考:Christian Bau,http://groups.google.com/group/comp.lang.c/msg/f0d8751e95c4c677
【解决方案2】:

只是因为你在做

(c?c:0)++;

如果你不让“++”发生,你就会得到你想要的。

#include <stdio.h>

int main(int argc, char const *argv[]) {
  int c = 0;
  /*  (c?c:0)++;  */
  printf("%i \n", (c?c:0)++ );
  return 0;
}

输出是:

$ gcc -o ternary ternary.c 
$ ./ternary 
0 

gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

【讨论】:

  • 这也不是有效的 C,你的意思是 (c?c:0)+1 我猜
  • 我理解的方式是:(c?c:0)++;——它会检查 c 是否存在。它在这种情况下(以及在所有情况下);它会做:(value of c)++。这给出了 1. 这有什么问题?
  • 三元运算符的结果不是左值
  • 谢谢大卫。 (如果可能的话)你能解释一下为什么这是一个要求吗?只是想了解为什么在这种特殊情况下左值是必须具有
  • @hari: ++ 对可修改的左值进行操作,否则您希望它更新什么?
【解决方案3】:

我也遇到了一些与此相关的奇怪现象。似乎三元条件的结果可以在 gcc 3.3.2 中被视为左值,但在 gcc 4.6 中却不是(我还没有准备好更多版本来进一步缩小范围)。事实上,使用 gcc 4.6 编译 gcc 3.3.2 是不可能的,因为 gcc 4.6 对左值的构成更加挑剔。

来自 gcc 3.3.2 源代码的另一个示例,它不能与 gcc 4.6 一起编译:

char *x = ...;
*((void**)x)++ = ...;

gcc 4.6 可以将强制转换的结果视为左值并增加它,但 gcc 4.6 不会。

我也没有相关的标准可以查明这是官方标准中改变的东西,或者只是 gcc 在某个阶段允许的东西。

还请注意,C++ 允许三元运算符返回一个左值,尽管您仍然不能递增 0。所以这是有效的 C++,但不是有效的 C:

int c = 0, d = 0;
(c?c:d)++;

【讨论】:

    猜你喜欢
    • 2016-10-14
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 2020-11-23
    • 2011-03-16
    相关资源
    最近更新 更多