簡體   English   中英

c中的運算符優先級為%,!=,=和','

[英]Operator precedence in c with %,!=,= and ','

在下面的代碼段中

int jo=50;
if( jo =(rand()%100), jo!=50)
{
    printf("!50");
}   
  1. %具有最高優先級,因此rand()%100將首先執行
  2. !=的優先級大於=所以jo!= 50應該執行正確嗎?
  3. ,當我首先執行賦值時,仍然具有最少的優先權然后!=然后,。 我得到一個輸出!50為什么?

問題是“序列點”:

http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html

問題與安全表達

什么是渲染賦值x [i] = i ++ + 1; 一個有問題的,而賦值i = 2; 從某種意義上說,它的結果是明確的,可預測的,是無害的嗎? 關鍵在於表達式x [i] = i ++ + 1; 有兩個對變量i的訪問,其中一個訪問,即i ++,是一個修改訪問。 由於未定義序列點之間的評估順序,因此我們不知道在讀取之前是否將對其進行修改,或者在修改之前是否將對其進行讀取。 因此,如果訪問是一個修改,問題的根源是對序列點之間的變量的多次訪問。

這是另一個例子。 如果在執行語句之前i和j的值為1和2,會發生什么?

 f(i++, j++, i+j); 

哪個值將作為第三個參數傳遞給函數f? 我們再一次不知道。 它可以是以下任何一種:3,4或5.它取決於函數參數的計算順序。
這里常見的誤解是參數將從左到右進行評估。 或者也許是從右到左? 事實上,語言定義沒有任何命令。

優先級控制執行順序。 優先級只控制分組-即,優先說什么操作數是每個操作,而不是每個操作發生。

在這個例子中,由於括號, %的優先級無關緊要 - 這些表示%的操作數是rand()100

的precedece ,為着低於=!=告訴我們的操作數=jo(rand()%100)和的操作數!=jo50

的操作數,然后jo = (rand() % 100)jo != 50

的定義,操作者說,第一個操作數進行評價時,則存在的序列點,然后第二個操作數進行評價。 所以這種情況下, jo = (rand() % 100)被完全評估,它將rand() % 100的結果存儲到jo ; 然后評估jo != 50 整個表達式的值是jo != 50的值。

好吧,序列點是正確的答案。 但是讓我們從教科書中翻譯出來。

逗號運算符具有一個特殊屬性:它確保首先評估其左側的內容。 所以,當你到達表達式時

 jo =(rand()%100), jo!=50

即使 !=比','更緊密地綁定 ,所以表達完全括號的表達式

 (jo =(rand()%100)),(jo!=50)

首先評估第一部分。

要記住這一點,你可以將逗號運算符代替或讀作“然后”,這樣

 j0=(rand()%100)

“接着”

 jo!=50.

將“優先權”視為“先做”是錯誤的。

請考慮以下代碼段:

f() + g() + h()

哪個添加操作具有更高的優先級,即對f()和g()的結果求和的那個,或者對該結果和h()求和的那個?

這是一個棘手的問題,因為根本不需要調用“優先級”。 但是仍然有一個操作順序,因為C中的函數調用引入了“序列點”,這就是C允許你確定“什么時候發生的事情”的原因。

在您的特定代碼中,您有一個逗號運算符 - 這與函數參數中的逗號標點符號完全不同 - 在此部分中:

jo = (rand() % 100), jo != 50

逗號運算符引入了一個序列點(就像對rand的函數調用一樣),因此我們知道rand運行並產生一個值,然后計算值% 100並將其分配給jo ,最后將jo50進行比較。

(在if控制表達式的評估之后還有一個序列點,每個語句結束的分號都有一個序列點。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM