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

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

     編輯:關於C++

引言

曾被 int * (* (*fp1) (int) ) [10]; 這類宣告搞得頭暈目眩?本文由淺入深教你破解複雜 C/C++ 宣告:從基本宣告、const 修飾符、typedef、函數指標,到終極武器——右左法則。注意:複雜宣告非良好程式風格,本文僅教導理解技巧。建議 1024×768 以上解析度閱讀。

基礎宣告解讀

核心原則:以變數名為中心,向外擴展閱讀。

  • int n; → 「n 是 int」
  • int *p; → 「p 是 int*」建議寫法:int *p; (星號貼變數),避免 int* p, q; 誤以為 q 也是指標(實則 q 是 int)。
  • char **argv; → 「argv 是指向 char* 的指標」
  • int RollNum[30][4]; int (*p)[4] = RollNum; int *q[5];
    • p:指向「4 個 int 陣列」的指標
    • q:5 個「int 指標」的陣列
  • 混合 * 與 &:
    • int **p1; → int 指標的指標
    • int *&p2; → int 指標的參考
    • int &*p3; → 錯誤:參考的指標不合法
    • int &&p4; → 錯誤:參考的參考不合法

const 修飾符完全解析

const 位置決定修飾對象:

  • const int n = 5; / int const m = 10; → 同為「const int」(整數常數),推薦前者。
  • const int *p; / int const *q; → 「指向 const int 的指標」(*p 不可改)
  • int * const r = &n; → 「const 指標,指向 int」 (r 不可改,*p 可改)
  • const int * const p = &n; → 「const 指標,指向 const int」 (雙重不可改)

多層 const 宣告對照表

宣告含義
char **p1;指向 char 指標的指標
const char **p2;指向 const char 指標的指標
char * const *p3;指向 char const 指標的指標
const char * const *p4;指向 const char const 指標的指標
char ** const p5;const 指標,指向 char 指標
const char ** const p6;const 指標,指向 const char 指標
char * const * const p7;const 指標,指向 char const 指標
const char * const * const p8;const 指標,指向 const char const 指標

typedef 簡化複雜宣告

typedef 可建立型別別名,解決「* 僅能修飾變數不能修飾型別」的問題:

typedef char * PCHAR;
PCHAR p, q;  // p、q 皆為 char*

遞迴 typedef 範例

typedef char * a;           // a: char*
typedef a b();              // b: 回傳 char* 的函數
typedef b *c;               // c: 指向 b 類型函數的指標
typedef c d();              // d: 回傳 c 的函數
typedef d *e;               // e: 指向 d 類型函數的指標
e var[10];                  // var: 10 個 e 的陣列

結構體常用寫法

typedef struct tagPOINT {
    int x, y;
} POINT;
POINT p;  // C/C++ 通用,C 中免寫 struct

函數指標宣告

最易混淆的宣告類型。範例:

  • int (*p)(char); → 指向「接受 char、回傳 int 的函數」的指標
  • char ** (*p)(float, float); → 指向「接受兩 float、回傳 char** 的函數」的指標
  • void * (*a[5])(char * const, char * const); → 5 個指標的陣列,各指向「接受兩 const char*、回傳 void*」的函數

右左法則 — 終極解讀技巧

規則:從變數名開始,向右讀,再向左讀。遇到括號反向。括號內讀完跳出。重複直到結束。

修正:起點必須是變數名,非最內層括號。

實戰演練 1

int * (* (*fp1) (int) ) [10];
  1. 變數名 fp1
  2. 向右遇 ),向左見 * → 指標
  3. 跳出括號,遇 (int) → 接受 int 參數的函數
  4. 向左見 * → 回傳指標
  5. 跳出括號,向右見 [10] → 10 元素陣列
  6. 向左見 * → 指標
  7. 向左見 int → int 型別

結論:fp1 是函數指標,該函數接受 int,回傳指向「10 個指標陣列」的指標。

實戰演練 2

int *( *( *arr[5])())();
  1. arr
  2. 向右 [5] → 5 元素陣列
  3. 向左 * → 指標
  4. 跳出,向右 () → 無參函數
  5. 向左 * → 回傳指標
  6. 跳出,向右 () → 無參函數
  7. 向左 * → 回傳指標
  8. 向左 int → int

結論:arr 是 5 元素陣列,元素為指標,指向「無參函數」,該函數回傳指標,指向「無參函數」,該函數回傳指標,指向 int。

更多範例速讀

宣告右左法則速讀結果
float ( * ( *b()) [] )();b: 函數,回傳指標,指向陣列,陣列元素為指標,指向回傳 float 的函數
void * ( *c) ( char, int (*)());c: 指標,指向函數,接受 char 與函數指標(無參、回傳 int),回傳 void*
void ** (*d) (int &, char **(*)(char *, char **));d: 指標,指向函數,接受 int& 與函數指標(接受 char*、char**、回傳 char**),回傳 void**
float ( * ( * e[10]) (int &) ) [5];e: 10 元素陣列,元素為指標,指向函數(接受 int&、回傳指向 5 float 陣列的指標)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved