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

C語言聲明與定義深度解析(上):指針陣列、數組指針、const修飾符優先級

     編輯:關於C

C 語言聲明語法以「聲明形式模仿使用形式」為哲學,但導致優先級極其複雜。本文系統梳理指針陣列與數組指針區別、const 修飾規則、結構體/聯合體/枚舉聲明細節,助你破解聲明迷宮。

核心哲學與優先級陷阱

「聲明形式模仿使用形式」:int *p[4] 使用時寫 *p[i],形式相似。

代價:15 級優先級,無法直觀左到右閱讀。

經典雙子星:指針陣列 vs 數組指針

int *p[5];      // 指針陣列:本質是陣列,元素是 int*
int (*p)[5];    // 數組指針:本質是指針,指向 int[5]

解析步驟

聲明步驟 1步驟 2結論
int *p[5]p[5] → 陣列int * → 元素類型5 個 int 指針的陣列
int (*p)[5](*p) → 指針int [5] → 指向類型指向 5 元素 int 陣列的指針

關鍵:[] 優先級高於 *,括號改變結合順序。

const 修飾符定位法則

const int *p;     // p 可變,*p 不可變(const 在 * 左,近數據)
int const *p;     // 同上,等價
int *const p;     // p 不可變,*p 可變(const 在 * 右,近指針)

口訣:const 貼近誰就修飾誰。

結構體 struct 聲明細節

匿名結構體直接定義變量

struct { int x; int y; } pt1, pt2;  // 定義兩個變量

缺點:無法復用類型定義新變量。

加標籤復用

struct Point { int x; int y; };
struct Point pt1, pt2, pt3;  // 復用

typedef 別名

typedef struct { int x; int y; } Point;
Point pt1, pt2;  // 簡潔,但失去「是結構體」的語義提示

位域

struct Flags {
    unsigned int inactive : 1;
    unsigned int         : 1;   // 無名填充
    unsigned int test     : 6;
    short pid_id;
    struct Flags *next;
};
  • 類型必須為 int/unsigned int/signed int
  • 有無符號位域行為視編譯器實現
  • 建議聲明與變量定義分離,提升可讀性

聯合體 union 共享記憶體

union BitTag {
    uint8_t state;
    struct {
        uint8_t bit_1 : 4;
        uint8_t bit_2 : 4;
    } BIT;
};
  • 所有成員偏移 0 開始,重疊存儲
  • 同一時刻僅一個成員有效
  • 優點:省空間;缺點:需程式員記住當前類型
  • 嵌入式常用:同一字節解析為整體或位域

枚舉 enum 編譯期常量

enum Color { RED, GREEN=5, BLUE };  // RED=0, GREEN=5, BLUE=6
  • 默認從 0 起,手動賦值後續遞增
  • 優於 #define:調試器可見、類型檢查、作用域限制
  • 推薦用於狀態機、錯誤碼、旗標群

聲明讀取心法:右左法則

  1. 找到標識符
  2. 向右看:遇到 ()、[] 先處理
  3. 向左看:遇到 *、類型修飾符
  4. 重複直到結束
int *(*p[5])();  // p 是陣列[5] → 元素是指針 → 指向函數 → 返回 int*

下期預告

下篇將深入函數指針、複雜聲明實戰解析、cdecl 工具使用技巧。

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