2012-10-23 61 views
17

語言設計者,選擇了在下列情況下的花括號可選:爲什麼C函數語言中的花括號不是可選的?

if (a) 
    b 
while (a) 
    b 
... 

爲什麼在功能不準一樣,這樣的嗎?

int add(int a, int b) 
    return a + b; 
+0

也許因爲一個函數必須知道它的身體具體包含什麼。 – Afaq

+0

無論函數還是條件/循環構造,編譯時都必須知道主體的長度和內容,因此大括號只是組織指令的方式。 – sean

+2

這個問題的答案几乎保證是推測性的。很確定這是脫離主題。 –

回答

24

我確信這會弄亂語法。例如會有這個空函數定義之間沒有區別......

void empty() 
{ 
    ; 
} 

...而這個函數聲明:

void empty(); 
+3

你釘了它。 +1 –

2

如果我想推測,我會說這是因爲函數通常包含多個語句,而if或while語句通常只包含一個語句。而且,由於在C++中允許忽略{}會導致成員函數的歧義,因此它被證明是有遠見的。例如:

struct s 
{ 
    void f() const int i; //does const refer to int i or the function? 
} 
+0

那麼這個聲明實際上做了什麼? – djechlin

+0

@djechlin:它導致編譯器錯誤,因爲{}對函數不是可選的。我的觀點是,如果他們是這樣,那麼會導致C++中的含糊不清。羅伯特庫珀的答案表明,它也會在C中引起歧義。 –

4

我不確定他們是否「選擇」了這一點。相反,這種能力可以忽略if,while,for等的大括號,作爲他們指定語法的自然結果。語法禁止它的功能可能是因爲舊式函數聲明。

3

沒有固定的關鍵字與函數定義相關。有if/else/for/while/switch有一個這樣的關鍵字標誌着邏輯控制結構的開始。

即使上下文允許我們人類辨別int some_name (some_expression) some_other_expressions;是一個函數 - 在編程實踐中(儘管明確可行),需要很多回溯才能確保令牌流前面的3-4-6個符號沒有任何變化這從函數聲明到其他東西。

編程語言解析器可以通過它的解析方法進行分類,或者它將令牌列表中的當前令牌和檢查下一個令牌是否證實「這是一個if」或「這是一個函數」,或者它需要一個最大的預見標記(2-3-6?),並確認「這可能是一個函數」,「現在我看到第5個標記這肯定是一個函數」,或者它使用了一種變量前瞻方法的回溯根據需要在令牌列表中遙遙領先,以確保我們正在研究的構造不是別的。

1

大括號是「如果」和「不可選組件if-else「控制語句。 「if」控制語句的語法生成允許一個非終結符號遵循表達式。 「if-else」控制語句的語法生成允許一個非終止符號跟隨該表達式,一個非終止符號跟隨「else」終止符號。該非終端符號的名稱是<陳述>。

在控制結構(也稱爲控制語句)的上下文中,大括號屬於稱爲<化合物語句>語言非終結符(有時被稱爲<塊>)。非終端符號<複合語句>出現在<語句>語法生成的右側,這就是大括號可與「if」和「if-else」控制語句一起使用的原因(即,,複合語句語句)。

<statement> ::= <if-then-statement> | 
       <if-then-else-statement> | 
       <for-statement> | 
       <do-while-statement> | 
       ... 
       <compound-statement> 

<statement-list> ::= <statement> | <statement-list> <statement> 

<if-then-statement> ::= "if" "(" <expression> ")" <statement> 

<if-then-else statement> ::= "if" "(" <expression> ")" <statement> 'else' <statement> 

<compound-statement> ::= "{" <statement-list> "}" 

對於函數聲明中,<複合語句>非終結符是在<函數聲明>語法生產的右手邊的最後一個非終結符。

P.S.所有非終結符號都是語法產物。所有語法產品都會減少到一個或多個非終端和/或終端符號。終端符號是語言關鍵字。

相關問題