[英]Operator precedence in c with %,!=,= and ','
在下面的代碼段中
int jo=50;
if( jo =(rand()%100), jo!=50)
{
printf("!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)
和的操作數!=
是jo
和50
。
的操作數,
然后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
,最后將jo
與50
進行比較。
(在if
控制表達式的評估之后還有一個序列點,每個語句結束的分號都有一個序列點。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.