switch 語句里代碼有什麼限制嗎?

#include &
int main()
{
int x = 0;
void (*f1)(void);
switch(x)
{
case 1:
void (*f2)(void);//注釋掉就不報錯了
break;
}
}

在swith里使用了函數指針定義,然而編譯器報出如下錯,不知何故。

test3.c:9:7: error: expected expression
void (*f2)(void);
^
1 error generated.

編譯環境如下

Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
cc -std=c99 -g -O0 test3.c -Wall -lm -lpthread -o test3


這個問題的話,需要解釋清楚的話,需要明白Declaration,Statement和Block三個概念。

而這裡簡單的解釋,在C中,Declaration不同於Statement,而你的函數指針聲明即是Declaration。而 i = 3;這樣的賦值語句就是屬於Statement。而一個Block可以允許一系列的Declaration與Statement在一起,其中一個compound statement就是一個Block,這也為Block與Statement建立了更深的聯繫。

根據C11標準,switch語句的case與default語句限定格式如下:

case constant-expression : statement

default : statement

我們可以發現限制了case與default後面的為statement,而非declaration。所以,你這裡進行函數指針聲明是不對的。

上文提到了Block,即 {},C11定義的格式如下:

compound-statement:
{ block-item-list (opt) }

block-item-list:
block-item
block-item-list block-item

block-item:
declaration
statement

所以,可以發現,我們可以把聲明與語句放在一個Block裡面,變成compound-statement,那麼這樣就符合statement的要求了,所以你的問題解決方案很簡單:

#include &
int main()
{
int x = 0;
void (*f1)(void);
switch(x)
{
case 1:
{
void (*f2)(void);//注釋掉就不報錯了
}
break;
}
}

這也是為什麼加Block可以解決的原因。

當然,這隻限定於C,若是C++,你這個代碼不加Block也是可以通過的。

而這深層次的原因,自然也是因為C和C++的一些概念不同造成的。

在C++中,Declaration叫做Declaration-Statement,而在C++11標準6.3節也特別註明了:

A compound statement defines a block scope (3.3). [Note: A declaration is a statement (6.7). —end

所以,這也是為什麼你的例子不修改,放在C++編譯器也可以編譯通過的原因。


switch case里每個case不會自動給你一個單獨的代碼塊


這裡需要statement而你提供了一個declaration。。。


排名第一說得很清楚了

用漢字描述一下

case的語法是

case : 語句

你寫的

void (*f2)(void);

不是語句

所以無法通過語法

只是一個聲明

{
void (*f2)(void);
}

是一個語句(複合語句) 所以沒有問題

需要注意2個常見誤區

1 對於C語言而言 聲明不是語句

1 語句不一定要用分號結尾


講真

我在一堆ns之間看到了這個問題

簡直清流!


沒必要的話,最好避開用continue


一個case其實就是一個label,編譯器真是這麼實現的。既然是label,那你這肯定不對啦


與樓上幾位一樣,我也碰到過這個問題,最後也是加了大括弧作為一個block才搞定。


這是一條聲明語句。C 語言 case 裡面不允許聲明,除非你用大括弧括起來作為語句塊。


補充一句,即使c++也不要這樣寫,最好開一個獨立的block


推薦閱讀:

想要系統學習演算法,斯坦福大學開設的MOOC課程《Algorithms: Design and Analysis》合適嗎?
哪種編程語言的代碼可讀性比較高?
學習編程,讀大學的和自學的有何區別?
實際軟體工程中是否真的需要100%代碼覆蓋率(code coverage)?
除了計算機相關專業,大學裡哪些專業也在學習編程?

TAG:編程 | C編程語言 | C語言入門 |