繁体   English   中英

C 运算符中的评估顺序

[英]Order of Evaluation in C Operators

根据 C,PostIncrement(a++) > Dereference(*) > Assignment(=) 当我在 c 片段下执行此操作时,

#include <stdio.h>

int main(){

    int arr[]= {1,2,3};
    int *p = a;

    *p++ = 3;

    for(int i=0;i<3;i++){
        printf("%d ",arr[i]);  
    }

}

Output:3 2 3

但是如果我们在这个陈述中应用优先顺序,

 *p++ = 3;

该语句将按以下顺序进行评估:

  1. p++ 将被评估
  2. *p 将被取消引用。
  3. 然后 3 将使用赋值运算符分配给 *p

如果我们应用上述顺序,指向数组 arr 开头的 p 将首先递增并指向数组的第二个元素。 然后第二个元素的地址将被取消引用,然后 3 将分配给第二个索引。 所以我们预期的 output 应该是 1 3 3 但我得到的 output 是 3 2 3。

我知道我预期的 output 不正确。 如果您在此解释编译器的 output 的情况下的评估顺序,将会很有帮助。

优先级仅确定运算符与操作数的分组 - 它不控制计算表达式的顺序。 优先规则仅确定

*p++ = 3;

应该解析

*(p++) = 3; // as opposed to (*p)++ = 3 or *(p++ = 3)

并不是说操作按特定顺序执行。

++––运算符有一个结果和一个副作用 后缀++的结果是操作数的当前值; 副作用是增加操作数。 你的表达在逻辑上等同于

tmp = p;
*tmp = 3;
p = p + 1;

需要注意的是,对*tmp的分配和ptr的更新可以以任何顺序发生,它们甚至可以交错或并行执行。

后递增表达式的结果是操作数在递增之前的值。 因此,即使*p++ ++的 ++ 确实比*具有更高的优先级,后者也适用于p++表达式的结果,正如刚才提到的,它是p的初始值。

根据 C 标准(6.5.2.4 后缀递增和递减运算符)

2后缀 ++ 运算符的结果是操作数的值。 作为副作用,操作数 object 的值会递增(即,相应类型的值 1 会添加到其中)。 有关约束、类型和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论。 结果的值计算在更新操作数的存储值的副作用之前排序。 对于不确定顺序的 function 调用,后缀 ++ 的操作是单次评估。 具有原子类型的 object 上的后缀 ++ 是具有 memory_order_seq_cst memory 顺序语义的读-修改-写操作。

因此在这个声明中

 *p++ = 3;

表达式p++返回指针p的当前值,该指针指向数组的第一个元素。 取消引用的正是指向数组第一个元素的 this 指针。

所以这个说法

 *p++ = 3;

不等同于陈述

p++;
*p = 3;

“该声明将按以下顺序进行评估:

p++ 将被评估 *p 将被取消引用。 那么 3 将被分配给 *p 使用赋值运算符”

Post Increments 运算符不能那样工作。 您可以这样假设以便更好地理解。

  • 当 p++ 被评估时,首先,它的当前值存储在一个临时位置,然后发生增量。
  • 所有剩余的操作都对存储在临时位置的值执行。
  • 对于后续语句,使用递增值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM