c語言中實際上不存在賦值語句?

c primer plus中說道c其實不存在賦值語句,我們所認為的賦值語句其實為表達式語句,這句話如何理解?


首先需要分清楚表達式(Expression)和語句(Statement)。比如:

a = b

這是一個賦值表達式;而

a = b;

這是一個表達式語句(Expression statement,它是語句而不是表達式),它包含了賦值表達式 a = b。所以並沒有賦值語句的說法。


表達式語句(expression statement)是一個完整的辭彙,來源於C語言的語法說明

它的意思就是單條表達式構成的語句,就是表達式後面加一個分號

賦值語句是不存在的,只有賦值表達式。

而所謂的賦值表達式語句,只是賦值表達式和語句的合成詞而已。


c語言里還沒有變數(variable)呢


語句(statement)在C語言中一般指的是以分號結束的一行或多行代碼。賦值語句是前輩們為了方便初學者記憶和理解發明的概念,實際上賦值是一個運算符,而運算符加上左右值就組成了表達式(expression):

a op b

其中,op是運算符,a是左值,b是右值

對於多運算符的複雜表達式,編譯器會根據語法規則定義的運算符優先順序構造出一顆語法樹,語法樹中表達式樹一般是二叉樹。

比如t=a+b*c的表達式樹是這樣的:

=

t +

a *

b c

表達式樹的遍歷一般採用DFS(深度優先遍歷),將最深處的表達式計算然後將其結果作為父表達式的左值或右值繼續計算。DFS的典型實現為遞歸。


在c語言做解析時,賦值被規約為表達式,因此賦值可以出現在c語法中任何表達式可出現的地方。比如if語句的條件,或者作為另一個複雜表達式的一部分。

一些語言如python,賦值被規約為語句。這類語言中賦值只能作為一條語句出現,不能當做表達式出現在其他語句中間。


The syntax of C in Backus-Naur form 不用太糾結這個問題


研究這個問題有意義嘛?我覺得你研究一下,它們之間的反彙編是否不同,更有意義吧。


c一類的語言里賦值是用表達式,不然也就不會有諸如if(a=b) blabla;之類的悲劇了。

btw,為了避免上述悲劇,有些代碼是這麼寫的:

if(3 == abc)

{

abcd = 6;

return 0;

}

else if(127 == A)

{

return 1;

}

這樣一旦==少打了一個=,編譯就無法通過。


對比一下,某些語言是真的有賦值語句,比如python。賦值不再是表達式,不會產生值。因而能避免==少打一個=,成了賦值釀成的悲劇。


好久沒有寫c,印象中是這樣的,a=6;整個表達式的值是6,導致a被賦值6隻是整個表達式的副作用。所以b=(a=6); b拿到了表達式的值6。而整個表達式的值也是6,b被賦值6也是順帶的副作用導致的。。。


不覺得這樣講有啥問題,標準沒有可以自己造嘛。

賦值概念,語句概念搞明白後,我說一個語句里只有賦值表達式,就簡稱它為賦值語句,多好記,有啥問題(O_O)?


推薦閱讀:

為什麼GCC會把0xBE-0x33解釋為浮點數?
c語言中指針指向的非指針變數不能使用++或--嗎?
指針是如何記住步長的?
C中有沒有將一個函數轉變為另一個函數的函數(例如求導運算)?
函數實現的時候,將函數返回值另起一行書寫,這是一種好的代碼書寫風格么?

TAG:編程 | C編程語言 |