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

輕鬆看懂複雜 C/C++ 宣告:右左法則完整教學

     編輯:VC 教學

曾被 int * (* (*fp1) (int) ) [10]; 這類宣告搞暈?本文從基礎出發,循序漸進教你掌握「右左法則」,輕鬆解讀任何複雜宣告。注意:複雜宣告非良好程式風格,本文僅教導理解技巧。

基礎:簡單宣告

int n;           // n 是 int
int *p;          // p 是 int* (指向 int 的指標)
char **argv;     // argv 是 char** (指標的指標)

建議寫法:int *p; 而非 int* p;,避免 int* p, q; 誤以為 q 也是指標(實為 int)。

陣列與指標混合


int RollNum[30][4];
int (*p)[4] = RollNum;   // p 是指向「4 個 int 的陣列」的指標
int *q[5];               // q 是「5 個 int* 的陣列」

記住:[] 優先級高於 *,int *q[5] 解讀為 int *(q[5])。

指標與參考混合


int **p1;   // int 的指標的指標
int *&p2;   // int* 的參考
int &*p3;   // 錯誤:參考的指標非法
int &&p4;   // 錯誤:參考的參考非法(C++11 右值參考除外)

右左法則核心步驟

  1. 從變數名稱開始。
  2. 向右讀取直到遇到結尾或右括號 )。
  3. 向左讀取直到遇到開頭或左括號 (。
  4. 跳出括號後,繼續向右、向左交替,直到解讀完所有修飾詞。
  5. 最後加上基礎型別。

實戰演練

例 1:int * (* (*fp1) (int) ) [10];

  1. 從 fp1 開始。
  2. 向右:) 停止。
  3. 向左:* → 「是一個指標」。
  4. 跳出括號,向右:(int) → 「指向接受 int 參數的函式」。
  5. 向左:* → 「的指標」。
  6. 跳出括號,向右:[10] → 「回傳 10 元素陣列」。
  7. 向左:* → 「的指標」。
  8. 基礎型別 int。

結果:fp1 是一個指標,指向一個接受 int 參數的函式,該函式回傳一個指標,指向一個包含 10 個 int 指標的陣列。

例 2:void (*signal(int, void (*fp)(int)))(int);

經典 signal 函式宣告。依右左法則解讀:signal 是函式,接受 int 和函式指標,回傳函式指標(接受 int,回傳 void)。

typedef 簡化複雜宣告


typedef int (*FuncPtr)(int);           // 函式指標型別
typedef int (*(*FuncPtrPtr)(int))[10]; // 更複雜的型別
FuncPtrPtr fp1; // 瞬間清爽

善用 typedef 或 C++11 using 別名,將複雜宣告封裝為可讀型別名稱,是工程實務最佳做法。

const 修飾詞位置

  • const int *p / int const *p:指向常數整數的指標(資料不可改)。
  • int * const p:常數指標(指標本身不可改,指向的資料可改)。
  • const int * const p:常數指標指向常數整數。

口訣:* 左邊的 const 修飾資料,右邊修飾指標。

總結

掌握右左法則,配合 typedef,任何宣告都能精準解讀。但實際專案中,請盡量避免過度複雜的宣告,改用型別別名提升可維護性。

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