1. const 關鍵字
? ? a) ?const int a;
? ? b) ?int const a;
? ? c) ?const int *a;
? ? d) ?int * const a;
? ? e) ?int const * const a;
解析:
? ? a) ?a為一個int型變量,在它被定義時就應當對其初始化,因為以后就沒有機會再去改變它了。
? ? b) ?與 a) 是一個意思,const 與 int 的位置可以互換。
? ? c) ?const 與 int 修飾的都是 (*a) ,這里的a是一個指向 int 型變量的指針,指針 a 的值可以被修改,(*a) 即 a 指向的變量不能被修改。
? ? d) ?const 修飾 a, 而int 修飾 (*a) ,這里的a是一個指向 int 型變量的指針,指針 a 的值不能被修改,(*a) 即 a 指向的變量可以被修改。?
? ? e) ?指針 a 的值與 (*a)即a指向的變量均不能被修改。
總結:
? ? 1) ?如果 const 與 int 是挨在一起的,中間沒有*,則兩者的位置是可以互換的。
? ? 2) ?如果 const 或是 int 之后是*,則 const 或是 int 修飾的是(*a),即修飾的是指針 a 指向的變量。
?
2. (*((void?(*)(?))0x80004000)) (?)
解析:
? ? 先看?(void?(*)(?))0x80004000 。
? ? 其中的?void?(*)(?) 是函數指針類型,該函數的形參為空,返回值類型為 void 。
? ? 于是,(void?(*)(?))0x80004000 就是表示,將?0x80004000 強制轉換為?void?(*)(?) 類型的函數指針,即0x80004000是某函數的入口地址。
? ? 然后,請回憶一下 (*p)() 是什么意思?沒錯,這是用函數指針調用函數的形式。
? ? 那么,(*((void?(*)(?))0x80004000)) (?) 就是表示,調用某一個函數, 該函數的入口地址為0x80004000,該函數的形參為空,無返回值。
?
3. void * ( * (*fp1)(int))[10];?
? ? float (*(* fp2)(int,int,int))(int);
? ? int (* ( * fp3)())[10]();
? ? 分別表示什么意思??
解析: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? 1. void * ( * (*fp1)(int))[10]; ??fp1是一個指針,指向一個函數,這個函數的參數為int型,函數的返回值是一個指針,這個指針指向一個數組,這個數組有10個元素,每個元素是一個void*型指針。
? ? 2. float (*(* fp2)(int,int,int))(int); ??fp2是一個指針,指向一個函數,這個函數的參數為3個int型,函數的返回值是一個指針,這個指針指向一個函數,這個函數的參數為int型,函數的返回值是float型。?
? ? 3. int (* ( * fp3)())[10](); ??fp3是一個指針,指向一個函數,這個函數的參數為空,函數的返回值是一個指針,這個指針指向一個數組,這個數組有10個元素,每個元素是一個指針,指向一個函數,這個函數的參數為空,函數的返回值是int型。?
?
4. 有關指針的數據類型的小結
定義 | 含義 |
int i; | 定義整型變量i |
int *p; | p為指向整型數據的指針變量 |
int a[n]; | 定義整型數組a,它有n個元素 |
int *p[n]; | 定義指針數組p,它由n個指向整型數據的指針元素組成 |
int (*p)[n]; | p為指向含n個元素的一維數組的指針變量,每一個元素均為整型數據 |
int (*p)[n](); | p為指向含n個元素的一維數組的指針變量,每一個元素均為一個函數指針,該函數無形參,返回int型數據 |
int f(); | f為帶回整型數值的函數 |
int *p(); | p為帶回一個指針的函數,該函數指向整型數據 |
int (*p)(); | p為指向函數的指針,該函數返回一個整型數據 |
int **p; | p為一個指針變量,它指向一個指向整型數據的指針變量 |
參考文檔:《徹底搞定C指針》