【问题标题】:Precedence of assignment within a conditional operator条件运算符中赋值的优先级
【发布时间】:2012-12-09 18:07:29
【问题描述】:

我创建了这个简单的程序来自动生成要在 Avisynth scipt 中使用的帧序列:

#include <stdio.h>

int main(void) {

    const int step = 3;
    const int arr[] = {31997, 31998, 32001};
    int i, ii = 0;

    for(i = 32002; i <= 32121; i += step, (sizeof(arr)/sizeof(int) - 1 ) != ii ? ++ii : ii = 0) {

        printf("freezeframe(%d,%d,%d)\n", i, i + step, arr[ii]);

    }

    return 0;
}

在 GCC 4.6.2 中使用 MinGW,我收到此错误:需要左值作为赋值的左操作数。

通过在 ii=0 周围使用括号即可轻松解决该问题。但是,我不明白为什么这是一个错误。赋值运算符不应该先求值吗?

【问题讨论】:

  • 写这样的代码,你活该受苦。
  • @DavidHeffernan 我知道。这只是为了手头的一项简单任务。

标签: c operator-precedence


【解决方案1】:

条件运算符的优先级高于 C 中的赋值运算符。

(sizeof(arr)/sizeof(int) - 1 ) != ii ? ++ii : ii = 0

被评估为

((sizeof(arr)/sizeof(int) - 1 ) != ii ? ++ii : ii) = 0

为了快速提醒 C 中的运算符优先级,您可以查看以下内容:

http://www.kernel.org/doc/man-pages/online/pages/man7/operator.7.html

【讨论】:

  • "条件运算符的优先级高于 C 中的赋值运算符。" - 实际上,没有。 C 中运算符的优先级取决于它们的上下文,不能简单地通过优先级表正确描述。事实上,这段代码应该编译得很好。
  • @H2CO3 为什么要编译好?也许在 C++ 中,但不是 C。请参阅我的答案。
  • @Pubby 说得好,+1。 (是的,这确实是一个编译器错误。)
【解决方案2】:

维基百科有一个简短的部分对此进行了解释:http://en.wikipedia.org/wiki/Operators_in_C_and_C++#Notes

C中条件运算符的语法是

logical-OR-expression ? expression : conditional-expression

请注意,assignment-expression被视为conditional-expression,条件表达式不能位于赋值表达式的左侧,因此从技术上讲它是语法错误。见语法:http://www.lysator.liu.se/c/ANSI-C-grammar-y.html

但是,GCC (错误地)将其解析为:

((sizeof(arr)/sizeof(int) - 1 ) != ii ? ++ii : ii) = 0

这是一个语义错误,因为++i 不是左值表达式。

【讨论】:

  • 非常感谢。这是我第一次知道优先级并不是唯一决定评估顺序的因素。
【解决方案3】:

如果您以这种方式编写代码,则始终建议使用括号

(sizeof(arr)/sizeof(int) - 1 ) != ii ? ++ii : ii = 0

喜欢

(((sizeof(arr)/sizeof(int) - 1 ) != ii ? ++ii : ii) = 0)

10 次中有 9 次你会卡住。

所以养成放括号的习惯,这不会对编译器造成任何开销!!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-14
    • 2013-03-27
    • 2020-08-22
    • 2015-08-24
    • 2020-03-22
    • 2018-09-28
    相关资源
    最近更新 更多