天天看點

typedef、#define、指針常量和常量指針

一、typedef用法:

①     定義一種類型的别名,而不隻是簡單的宏替換。可用作同時聲明指針類型的多個對象。陷阱:typedef char* TCHAR;

TCHAR pa, pb;//pa和pb都是指針類型。#define不能達到此效果。

陷阱:typedef char* PSTR;

int mystrcmp(const PSTR, const PSTR);const PSTR相當于char*嗎?不是的,它實際上相當于char* const。const給了整個指針以常量性。要想定義一個常量指針,需:

typedef const char* cpstr;

②     定義與平台無關的類型。如定義一個叫REAL的浮點類型,

在平台1上實作為:typedef long double REAL;在平台2上實作為:typedef double REAL;

在平台3上實作為:typedef float REAL;即當跨平台時,隻需修改typedef本身。

③     為複雜的聲明定義一個新的簡單的别名。方法是:在原來的聲明裡逐漸用别名替換一部分複雜聲明,如此循環,把帶變量名的部分留到最後替換,得到的就是原聲明的簡化版。如:

Ø  原聲明:int *(*a[5])(int, char);

變量名為a,直接用一個新别名pFun替換a就可以了:

typedef int*(*pFun)(int, char);原聲明的最簡化版:pFun a[5];

Ø  原聲明:void (*b[10]) (void (*)());

變量名為b,先替換右邊部分括号裡的,pFunParam為别名一:

typedef void (*pFunParam)();

再替換左邊的變量b,pFunx為别名二:

typedef void (*pFunx)(pFunParam);

原聲明的最簡化版:pFunx b[10];

Ø  原聲明:doube(*)() (*e)[9];

變量名為e,先替換左邊部分,pFuny為别名一:

typedef double(*pFuny)();

再替換右邊的變量e,pFunParamy為别名二

typedef pFuny (*pFunParamy)[9];

原聲明的最簡化版:pFunParamy e;

了解複雜聲明可用的“右左法則”:

從變量名看起,先往右,再往左,碰到一個圓括号就調轉閱讀的方向;括号内分析完就跳出括号,還是按先右後左的順序,如此循環,直到整個聲明分析完。舉例:

int (*func)(int *p);

首先找到變量名func,外面有一對圓括号,而且左邊是一個*号,這說明func是一個指針;然後跳出這個圓括号,先看右邊,又遇到圓括号,這說明(*func)是一個函數,是以func是一個指向這類函數的指針,即函數指針,這類函數具有int*類型的形參,傳回值類型是int。

int (*func[5])(int *);

func右邊是一個[]運算符,說明func是具有5個元素的數組;func的左邊有一個*,說明func的元素是指針。跳出這個括号,看右邊,又遇到圓括号,說明func數組的元素是函數類型的指針,它指向的函數具有int*類型的形參,傳回值類型為int。

常見用法舉例:

Ø  數組類型定義:typedef int arr[2];arr相當于int[2]定義。arr a;相當于int a[2];

Ø  函數指針:typedef int (*func)(void);func等價于int(*)(void)。func pf等價于int (*pf)(void);

二、#define:預處理指令。在預編譯(即預處理)階段進行簡單替換,不作正确性檢查。用途:

①     定義宏。

②     頭檔案保護符。(本質同③)

③     做一些條件判斷。

三、常量指針和指針常量:const在*前為常(首字母為C)量指針(首字母為Z),即const在*前為正序(CZ);const在*後為指(首字母為Z)針常量(首字母為C),即const在*後為倒序。常量指針-----所指向的位址可變,位址存儲的内容不可變。指針常量-----所指向位址不可變。