2017-03-15 78 views
3

我讀的是this earlier answer,它有一段我無法理解的C代碼。它本質上是這樣的:是什麼(int_1 + = * pointer ++ = int_2 ++)<int_3是什麼意思?

if((int_1 += *pointer++ = int_2++) < int_3) continue; 

我可以打破它是這樣的 -

這是什麼意思?我可以得到關於這一點:

if((int_1 = int_1+ *pointer++ (unsure about this part))<int_3) continue; 
+12

作爲供參考,這不會是「專家語法」。這將是「高度混淆,寫得不好的語法,旨在混淆你」。 :-) – templatetypedef

+0

@templatetypedef你打我幾乎相同的評論! –

+0

請問你爲什麼?你爲什麼想要理解那可怕的語法? –

回答

10

因此,對於初學者來說,這是真的,非常糟糕的C代碼。就像可怕的C代碼一樣。就像,我一直在C編碼很長一段時間,不得不拉起operator precedence chart因爲我從來沒有遇到過這樣可怕的事情。所以沒有理由寫這樣的東西 - 當然不是在生產代碼中,並且希望不是作爲課程的一部分,因爲你永遠不需要知道操作符優先級這個特殊的怪癖(來源:我教CS爲生)。我甚至可以說,你所引用的源代碼是不應該寫成這種方式的壞C代碼。

但是說到這裏,讓我們來分解它!這裏的核心表達是

(int_1 += *pointer++ = int_2++) < int_3 

在該內表達兩種賦值運算符,其具有相同的優先級和組從右到左。也就是說,這相當於

(int_1 += (*pointer++ = int_2++)) < int_3 

這意味着

  1. 增量int_2和存儲其舊值。
  2. 將該值存儲在pointer指向的位置,然後將指針前移到下一個位置。
  3. 將該值加到int_1
  4. 然後查看該值是否小於int_3

沒有理由做這樣的事情。只寫

int val = int_2; 
*pointer = val; 
int_1 += val; 

int_2++; 
pointer++; 

if (val < int_3) { 
    ... 
} 

所以呀!不要這樣寫代碼。永遠。 :-)從外面

+3

這讓我想起了我在80年代末/ 90年代早期工作過的僱主,他有一段軟件,A)對業務運作至關重要,B)未記錄,C)他們已經失去了消息來源。解決方案:不要弄清楚它做了什麼,以及如何,他們只是不斷地調用「魔術功能」,很高興知道它做了什麼,即使他們不太確定如何。這是財富1000強公司,BTW ... :-) –

+1

錯誤代碼,解決不好?難怪它是財富1000而不是財富500強。:-) – templatetypedef

+1

它通過避免'val'確實更清楚:'* pointer = int_2; int_1 + = int_2; int_2 ++; pointer ++; if(int_2 <= int_3){ ... } ' – ikegami

2

讓我們的工作,在:

if (...) continue; 

這是一個if-statement,用一個語句(continue)作爲它的身體。

continue語句只在循環中有效。所以,在某個地方有一個循環 - fordo ... whilewhile - 這個聲明就在裏面。

如果條件爲真,不管是什麼,continue都會導致循環主體的執行向前跳到循環體的末尾,評估循環的條件,並可能增加並開始下一個迭代(取決於環路防護,以及是否存在具有非空增量的for循環)。

現在讓我們來看看裏面:

(int_1 += *pointer++ = int_2++) < int_3 

這是一個括號表達式是與int_3比較。因此,我們有這樣的:

temp < int_3 

這是一個條件表達式,作爲一個if語句中使用,這樣你就可以弄清楚,是如何去上班。

括號內的表達式如下所示:

int_1 += *pointer++ = int_2++ 

有使用二元算。三元(三個參數)和二元(兩個參數)優先級低於一元(一個參數)運算符。所以=+=將被評估爲「最後」。事實上,賦值運算符是right-associative

這意味着,在給定的A = B = C像這樣的一個方案中,(其中=也可以是+=,或%=或其他),表達式將被佈置爲,如果它是:

A = (B = C) 

分組到右邊,而不是像+*那樣左邊分組,其中A + B + C變成(A + B)+ C。

所以你內心的表達將被分爲兩個部分:

int_1 +=    ( *pointer++ = int_2++ ) 

現在右手部分將首先評估:

*pointer++ = int_2++ 

有一個指針反引用(* )運營商和兩個後增加運營商。

後增量運算符計算到電流值無論你正在申請它,但隨後導致該值後評價來增加。所以int_2++真的是這樣的:

(temp = int_2, int_2 = int_2+1, temp) 

同樣,說*pointer++ = value真正含義:

*pointer = value 
pointer = pointer + 1 

所以,你有指針的當前值的目標被分配到的int_2現值,然後他們兩個都增加。

C定義了它的賦值運算符來返回賦值的右值。也就是說,要將存儲的值返回到賦值運算符左側的任何左值。在這種情況下,=賦值將返回int_2的當前值(增量前)。

所以,你有你的表達的最後一部分:

int_1 += ... 

知道了右邊的值(右值)將會是int_2現值,你的代碼加入這個值到int_1。 C的+=運算符是簡寫:L += RL = L + R相同,只是它僅評估一次L。所以最終的結果是像int_1 = int_1 + int_2得到執行。

您會記得賦值運算符會返回它們的賦值。特殊賦值操作符也是如此。在這種情況下,+=的結果將成爲構成您的if聲明的A < B比較的左側。

如果我們知道int_1int_2是什麼,那麼我們可以決定是否要< int_3,如果我們知道int_3是什麼。 ;-)