Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 复杂表达式的运算符优先级和求值顺序_C_Operator Precedence - Fatal编程技术网

C 复杂表达式的运算符优先级和求值顺序

C 复杂表达式的运算符优先级和求值顺序,c,operator-precedence,C,Operator Precedence,我正在查看以下代码: #include <stdint.h> void foo(uint32_t *pVal) { uint32_t i = 8; *pVal = i *= 10; } 但是,在从检查运算符优先级后,=的优先级高于*=的优先级,因此似乎*pVal的值应为8,i的值应为80 我错过了什么 编辑: 除了由给出的很好的答案外,还有一个很好的答案。您链接到的表显示了相同优先级的所有赋值运算符(包括=和*=):14 它们也是右关联的,因此正如预期的那样,x=y*=

我正在查看以下代码:

#include <stdint.h>

void foo(uint32_t *pVal)
{
  uint32_t i = 8;

  *pVal = i *= 10;
}
但是,在从检查运算符优先级后,
=
的优先级高于
*=
的优先级,因此似乎
*pVal
的值应为8,
i
的值应为80

我错过了什么

编辑


除了由给出的很好的答案外,还有一个很好的答案。

您链接到的表显示了相同优先级的所有赋值运算符(包括
=
*=
):14

它们也是右关联的,因此正如预期的那样,
x=y*=z
解析为
x=(y*=z)


如果
=
的优先级高于
*=
,则
x=y*=z
将解析为
(x=y)*=z
,这将是一个硬错误,因为
=
不会产生左值(您无法分配给赋值的结果)。如果
=
确实将其左操作数作为左值返回,则
(x=y)*=z
将具有未定义的行为,因为它在没有插入序列点的情况下修改了
x
两次。如果内部赋值后有一个序列点,
(*pVal=i)*=10
后变量的最终值将是
i=8
(未修改)和
*pVal=80


(使用Perl,它有一个返回左值的
=
,如上所述)

@AlexLop。它还说第一列是优先级。表中同一行中的所有行具有相同的优先级。@AlexLop。它是从上到下列出的“优先级”列,
1
是最高的,
15
是最低的。同一级别上的所有运算符都具有相同的优先级。谢谢您的回答。我很高兴我只是误解了图表。请注意,链接的优先表有错误(他们将cast运算符放在错误的组中,有17个组而不是15个组等)。大多数这样的表都有错误,因为C标准没有列出这样的表。有一次,我厌倦了所有这些糟糕的桌子,并试图自己做一张。但是,由于它是一个屏幕截图,所以格式很糟糕:/@Lundin我认为您的表是错误的,因为它将强制类型转换放在了错误的组中。强制转换是一元(前缀)运算符,不能有具有不同优先级的前缀运算符。此外,主表达式不是运算符。@melpomene一元运算符和强制转换在标准中属于不同的组(在C17草案6.5 p3中指定的分组),强制转换具有较低的优先级。@melpomene C标准C17 6.5.4是具有强制转换运算符的组(只有一个)。如语法所示,它的优先级低于一元运算符。我的表遵循标准的组和语法,与cppreference中的表不同。@Lundin我看到的是
cast expression:unary expression |…
unary expression:unary operator cast expression |…
,因此它们是相互递归的,且优先级都不高于另一个。他们在不同的组中的唯一原因是一种语法黑客,用
sizeof
消除歧义:根据语法,
sizeof(int)+0
明确地解析为
(sizeof(int))+0
,而不是
sizeof((int)+0)
(也就是说,这个表达式中没有强制转换)。
foo:                                    # @foo
        push    rbp
        mov     rbp, rsp
        mov     qword ptr [rbp - 8], rdi
        mov     dword ptr [rbp - 12], 8
        imul    eax, dword ptr [rbp - 12], 10
        mov     dword ptr [rbp - 12], eax
        mov     rdi, qword ptr [rbp - 8]
        mov     dword ptr [rdi], eax
        pop     rbp
        ret