首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言宣告優先序規則與 typedef 進階用法全解

     編輯:關於C語言

前言

C 宣告語法以「優先序規則」聞名遐邇,搭配 typedef 能大幅提升可讀性。本文系統整理解析步驟、名稱空間隔離、typedef vs 宏的本質差異,並給出實戰範本。

一、宣告解析「右左法則」

標準解析步驟:

  1. 從變數名出發。
  2. 優先處理括號內內容。
  3. 依優先序:後綴 ()(函式)、[](陣列) > 前綴 *(指標) > 型別修飾詞(const/volatile)。
  4. const/volatile 緊跟型別修飾型別,否則修飾左側最近的 *。

實戰解析

char * const *(*next)();
  1. next 是 ...
  2. (*next) → 指標
  3. (*next)() → 指向函式的指標
  4. *(*next)() → 函式回傳指標
  5. const *(*next)() → 回傳 const 指標
  6. char * const *(*next)() → 回傳「指向 char 的 const 指標」的指標

結論:next 是「指向函式的指標,該函式回傳『指向 char 的常數指標』的指標」。

二、typedef:型別別名而非文字替換

2.1 核心差異

特性#definetypedef
處理階段前處理(文字替換)編譯(語意分析)
可加修飾詞unsigned INT_PTR 合法unsigned MyIntPtr 錯誤
多變數宣告INT_PTR a, b; → int *a, b; (b 非指標)MyIntPtr a, b; 皆為指標
遞迴定義可能無限展開編譯器偵測循環

2.2 經典應用:signal 原型簡化

/* 原始原型:難以閱讀 */
void (*signal(int sig, void (*func)(int)))(int);

/* typedef 兩步走 */
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

三、C 的四大名稱空間

  1. 標籤名空間:goto label;
  2. 標記名空間:struct/union/enum 標記(struct Foo)
  3. 成員名空間:每個結構/聯合獨立(s.member)
  4. 一般識別碼名空間:變數、函式、typedef 名稱、列舉常數

不同名稱空間可重名:

struct Foo { int Foo; };      /* 合法:標記 vs 成員 */
typedef struct Foo Foo;       /* 合法:標記 vs typedef */
Foo Foo;                      /* 合法:typedef 名 vs 變數名 */

四、結構標記與 typedef 同時宣告陷阱

typedef struct Fruit { int weight; } Fruit;  /* 同時引入標記 Fruit 與型別 Fruit */
struct Fruit apple;    /* 以標記宣告 */
Fruit banana;          /* 以型別宣告 */

struct Veg { int weight; } Veg;  /* 標記 Veg + 變數 Veg(非型別!) */
struct Veg carrot;     /* 僅能用標記 */
Veg potato;            /* 錯誤:Veg 非型別名 */

類比:int i; i j; 同樣非法。

五、列舉型別現代用法

enum Color { RED = 1, GREEN, BLUE = 5, YELLOW }; /* RED=1, GREEN=2, BLUE=5, YELLOW=6 */
enum { MAX_SIZE = 1024 };  /* 匿名列舉,常數可直接用 MAX_SIZE */
  • 列舉常數為 int 常數運算式,可用於 case、位欄寬度、陣列大小。
  • 除錯器保留符號名,優於 #define。
  • C23 引入 enum : uint8_t { ... } 指定底層型別。

六、const 進階語意

const int *p;       /* p 可變,*p 唯讀 */
int * const p;      /* p 唯讀,*p 可變 */
const int * const p;/* 皆唯讀 */

/* 函式參數 */
void foo(const int *p);     /* 承諾不修改 *p */
void bar(int * const p);    /* 承諾不修改 p 本身(罕用) */
  • const 物件若未被 volatile 修飾且位址未逃逸,編譯器常直接以立即數替換,不配置儲存空間。
  • const 非「編譯期常數」(C 不支援 const int n; int a[n];),需用 enum 或宏。

宣告即文件,typedef 即抽象。善用「右左法則」解讀複雜宣告,用 typedef 封裝函式指標與平台相關型別,能讓 C 程式碼既精確又易維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved