February 1, 2026

Understanding complex C declarations

為什麼會有這篇文

自己對於 C 語言複雜宣告的掌握度還是偏低,所以撰文一邊練習一邊紀錄應該要如何閱讀 c 語言的宣告

很有用的網站

先來講一下基礎規則

The “right-left” rule is a completely regular rule for deciphering C declarations. It can also be useful in creating them.

在解讀 C 語言的宣告時順序是從右到左

symbols 讀法介紹

SymbolPronouncePosition
*as “pointer to”always on the left side
[ ]as “array of”always on the right side
( )as “function returning”always on the right side

(如果遇到左括號,則代表他是 ( ) 這個符號的開始下面的第二個練習可以看到如何操作)

小試身手

int *p[]

找到 identifier,這邊是 p,開始宣告 p is…

1
2
int *p[]
     ^

繼續往右邊看,看到 [

1
2
int *p[]
      ^

往右邊看,看到],這個 symbol 結束,我們可以得到 p is array of…

1
2
int *p[]
       ^

identifier 往左邊看,看到 *,我們可以得到 p is array of pointer to…

1
2
int *p[]
    ^

繼續往左邊看,看到 int,我們可以得到 p is array pointer to int

1
2
int *p[]
 ^

int *(*func())()

找到 identifier,這邊是 func ,開始宣告, func is…

1
int *(*func())()

往右看到 (,所以 func is function returning…

1
2
int *(*func())()
           ^

繼續往右看遇到 ),閉合起來了,所以回到 identifier 往左邊看

1
2
int *(*func())()
            ^

往左看到 *,所以 func is function returning pointer to…

1
2
int *(*func())()
      ^

再往左看到 (,被閉合起來了,回到剛剛右邊

1
2
int *(*func())()
     ^

回到剛剛右邊,看到右括號,繼續往右

1
2
int *(*func())()
              ^

繼續往右看到左括號,閉合起來,現在 func is function returning pointer to function returning…,右邊沒符號了,接下來回到左邊繼續分析

1
2
int *(*func())()
               ^

回到左邊看到 *,所以現在 func is function returning pointer to function returning pointer to…

1
2
int *(*func())()
    ^

繼續往左看到 int,所以 func is function returning pointer to function returning pointer to int

1
2
int *(*func())()
    ^

分析完畢,最後得到 func is function returning pointer to function returning pointer to int

int *var[10];

1
int *var[10]; 

*var(char,int);

1
int *var(char,int); 

int (*var)[10];

1
int (*var)[10]; 

int (*var)(char, int);

1
int (*var)(char, int); 

int (*var[10])(char, int);

1
int (*var[10])(char, int); 

int (*var(char, int))[10];

1
int (*var(char, int))[10]; 

int (*var(char, int))(int);

1
int (*var(char, int))(int); 

char (*var[10])(char ,int ()[10]);

1
char (*var[10])(char *,int (*)[10]); 

int *(*var(char , int ()[10]))[12]

1
int *(*var(char *, int (*)[10]))[12] 

int **(*var(char , int ()[12]))(unsigned int);

1
int **(*var(char *, int (*)[12]))(unsigned int); 

char (*var[10])();

1
char (*var[10])(); 

int *(*var())[10];

1
int *(*var())[10]; 

int **(*var())();

1
int **(*var())(); 

double ( var(unsigned long long (*)[74]))[12]

1
double *(* var(unsigned long long (*)[74]))[12]

Reference

https://gist.github.com/muxuezi/05b634728b93b710f217

https://magicjackting.pixnet.net/blog/posts/12060889356

https://www.youtube.com/watch?v=D-mCU1qKJcc