2008-09-18 74 views
41

我聽說過一些方法,但都沒有卡住。就我個人而言,我嘗試在C中避免複雜的類型,並嘗試將它們分解爲組件typedef。你如何閱讀C聲明?

我現在正在維護一個所謂'三星程序員'的遺留代碼,而且我很難讀一些***代碼[] []。

您如何閱讀複雜的C聲明?

+2

眼睛工作......但如果你用Windows卡住了,我想你可以試試Narrator。 – Shog9 2008-09-18 01:05:24

+5

「三星級程序員」是否意味着他所宣稱的所有類型中至少有三顆星? – 2008-09-18 01:06:19

+3

很多,這是一個壞的c程序員的老學校侮辱 – 1729 2008-09-18 01:08:23

回答

3

回到我在做C時,我使用了一個名爲「cdecl」的程序。看起來它在Ubuntu Linux中的cutils或cdecl包中,並且可能在其他地方提供。

5

一個字:cdecl

該死,通過15秒捱打!

28

本文介紹了一種相對簡單的規則7可以讓你讀任何C的聲明,如果你發現自己想要或者需要手動執行:http://www.ericgiguere.com/articles/reading-c-declarations.html

  1. 查找標識符。這是你的出發點。在一張紙上,寫上「聲明標識符爲」。
  2. 向右看。如果沒有任何內容,或者有右括號「)」,則轉到步驟4.
  3. 您現在位於數組(左括號)或函數(左括號)描述符上。可能有一系列的這些結束,無論是右括號還是結尾(分號或用於初始化的「=」)。對於每個這樣的描述符,從讀取從左到右:

    • 如果空數組「[]」,寫入
    • 「的數組」如果與尺寸的陣列,寫
    • 「的數組大小」如果函數「()」寫「返回函數」

    停在不匹配的圓括號或者說明符的末尾,以先到者爲準。

  4. 返回到開始位置並向左看。如果沒有任何東西,或者有左括號「(」,轉到第6步。
  5. 您現在被定位在一個指針描述符「*」上。左邊可能有一個這樣的序列,一個不匹配的左括號「(」或者聲明符的開頭,從右到左讀取,爲每個指針描述符寫入「指向」的指針,停在不匹配的括號或聲明符的開頭,以先到者爲準。
  6. 在這一點上,你有一個加括號的表達式或完整的聲明。如果您有一個加括號的表達式,請將其視爲您的新起點並返回到步驟2.
  7. 記下類型說明符。停止。

如果你很好用的工具,那麼我第二個建議使用程序cdeclhttp://gd.tuwien.ac.at/linuxcommand.org/man_pages/cdecl1.html

1

CDECL提供了一個命令行界面,讓我們試試看:

另一示例

explain int (*IMP)(ID,SEL) 
declare IMP as pointer to function (ID, SEL) returning int 

然而噸這裏是關於書中「C深層的祕密」一整章,在C.

名爲「解讀聲明問候 弗里德里希

20

我一般用什麼有時被稱爲‘右手順時針規則’。 它是這樣的:

  • 從標識符開始。
  • 轉到它的右側。
  • 然後順時針移動到左側。
  • 順時針方向移動到右側。
  • 只要聲明沒有被完全解析,就這樣做。

有有被照顧的一個額外的元規則:

  • 如果有括號,遷出前完成括號的每個級別。

在這裏,'去'和'移動'的地方意味着在那裏讀取符號。該規則是:

  • * - 指針
  • () - 函數返回
  • (int, int) - 功能以兩個整數並返回
  • intchar等 - intchar等。
  • [] - 數組
  • [10] - 十個數組

因此,舉例來說,int* (*xyz[10])(int*, char)讀作:

XYZ是

陣列10

指針

函數採取一個int *和炭並返回

int *

0

自動化的解決方案是的cdecl。

一般情況下,您使用它的方式聲明變量。例如,取消引用指針p爲:

 
char c = * p 

你在一個類似的尋找方式聲明它:

 
char * p; 

也是一樣的毛茸茸的函數指針。讓我們聲明f是很好的「指向返回指向int的函數的指針」,並且外部聲明只是有趣的。這是一個指向函數的指針,所以我們先從:

 
extern * f(); 

它返回一個指向一個int,在前面,所以某個地方有還有的

 
extern int * * f(); // XXX not quite yet 

現在,這是正確的關聯?我永遠不會記住,所以用一些括號。

 
extern (int *)(* f)(); 

聲明它的使用方式。

0

從右到左閱讀。

***code[][] 
  • 代碼[] []是一multidimenstional陣列
  • *代碼[] []是一multidimenstional數組指針
  • **代碼[] []是一multidimenstional陣列指針的指針
  • ***代碼[] []是一multidimenstional陣列指針的指針的指針
0

對面照明部在「The Development of the C Language來到「:

對於這種組合類型的每個對象,已經有一種方法來提及基礎對象:索引數組,調用函數,在指針上使用間接運算符。類比推理導致名稱的聲明語法鏡像名稱通常出現的表達式語法的名稱。因此,

int i, *pi, **ppi;

聲明的整數,一個指針到一個整數,指針的指針的整數。這些聲明的語法反映了當在表達式中使用時,i,* pi和** ppi都會產生int類型。類似地,

int f(), *f(), (*f)();

聲明函數返回一個整數,返回指針到一個整數的函數,一個指向函數返回的整數;

int *api[10], (*pai)[10];

聲明指針數組爲整數,和一個指向整數數組。在所有這些情況下,變量的聲明類似於它在聲明頭部命名的表達式中的用法。