简体   繁体   English

C 运算符中的评估顺序

[英]Order of Evaluation in C Operators

As per C, PostIncrement(a++) > Dereference(*) > Assignment(=) When I execute this below c snippet,根据 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 Output:3 2 3

But if we apply order of precedence in this statement,但是如果我们在这个陈述中应用优先顺序,

 *p++ = 3;

The statement will be evaluated in the following order:该语句将按以下顺序进行评估:

  1. p++ will be evaluated p++ 将被评估
  2. *p will get dereferenced. *p 将被取消引用。
  3. then 3 will be assigned to *p using the assignment operator然后 3 将使用赋值运算符分配给 *p

If we apply the above order, p which is pointing to the start of the array arr, will get incremented first and point to the second element of the array.如果我们应用上述顺序,指向数组 arr 开头的 p 将首先递增并指向数组的第二个元素。 Then second element's address will get dereferenced and then 3 will be assigned to the second index.然后第二个元素的地址将被取消引用,然后 3 将分配给第二个索引。 So our expected output should be 1 3 3 But the output I got is 3 2 3.所以我们预期的 output 应该是 1 3 3 但我得到的 output 是 3 2 3。

I know that my expected output is not correct.我知道我预期的 output 不正确。 It'll be helpful if you explain the order of evaluation here in this case of the output of the compiler.如果您在此解释编译器的 output 的情况下的评估顺序,将会很有帮助。

Precedence only determines the grouping of operators with operands - it does not control the order in which expressions are evaluated.优先级仅确定运算符与操作数的分组 - 它不控制计算表达式的顺序。 Precedence rules only determine that优先规则仅确定

*p++ = 3;

should parsed as应该解析

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

not that operations be executed in a specific order.并不是说操作按特定顺序执行。

The ++ and –– operators have a result and a side effect . ++––运算符有一个结果和一个副作用 The result of postfix ++ is the current value of the operand;后缀++的结果是操作数的当前值; the side effect is to increment the operand.副作用是增加操作数。 Your expression is logically equivalent to你的表达在逻辑上等同于

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

with the caveat that the assignment to *tmp and the update of ptr can happen in any order, and they can even be interleaved or executed in parallel.需要注意的是,对*tmp的分配和ptr的更新可以以任何顺序发生,它们甚至可以交错或并行执行。

The result of a post-increment expression is the value of the operand before it is incremented.后递增表达式的结果是操作数在递增之前的值。 Thus, even though the ++ in *p++ does, indeed, have higher precedence than the * , the latter is applied to the result of the p++ expression which is, as just mentioned, the initial value of p .因此,即使*p++ ++的 ++ 确实比*具有更高的优先级,后者也适用于p++表达式的结果,正如刚才提到的,它是p的初始值。

According to the C Standard (6.5.2.4 Postfix increment and decrement operators)根据 C 标准(6.5.2.4 后缀递增和递减运算符)

2 The result of the postfix ++ operator is the value of the operand. 2后缀 ++ 运算符的结果是操作数的值。 As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).作为副作用,操作数 object 的值会递增(即,相应类型的值 1 会添加到其中)。 See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers.有关约束、类型和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论。 The value computation of the result is sequenced before the side effect of updating the stored value of the operand.结果的值计算在更新操作数的存储值的副作用之前排序。 With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation.对于不确定顺序的 function 调用,后缀 ++ 的操作是单次评估。 Postfix ++ on an object with atomic type is a read-modify-write operation with memory_order_seq_cst memory order semantics.具有原子类型的 object 上的后缀 ++ 是具有 memory_order_seq_cst memory 顺序语义的读-修改-写操作。

Thus in this statement因此在这个声明中

 *p++ = 3;

the expression p++ returns the current value of the pointer p that is a pointer that points to the first element of the array.表达式p++返回指针p的当前值,该指针指向数组的第一个元素。 It is this pointer to the first element of the array that is dereferenced.取消引用的正是指向数组第一个元素的 this 指针。

So this statement所以这个说法

 *p++ = 3;

is not equivalent to the statements不等同于陈述

p++;
*p = 3;

"The statement will be evaluated in the following order: “该声明将按以下顺序进行评估:

p++ will be evaluated *p will get dereferenced. p++ 将被评估 *p 将被取消引用。 then 3 will be assigned to *p using the assignment operator"那么 3 将被分配给 *p 使用赋值运算符”

Post Increments operator doesn't work like that. Post Increments 运算符不能那样工作。 You can assume like this for better understanding.您可以这样假设以便更好地理解。

  • When p++ gets evaluated, first, its present value is stored at a temporary location then the increment takes places.当 p++ 被评估时,首先,它的当前值存储在一个临时位置,然后发生增量。
  • All remaining operations are performed on the value stored in temporary location.所有剩余的操作都对存储在临时位置的值执行。
  • For subsequent statements incremented value is used.对于后续语句,使用递增值。

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

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