簡體   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