轉載:https://blog.csdn.net/EbowTang/article/details/30050705
參考文章:
1,typedef的用法總結,http://www.cnblogs.com/csyisong/archive/2009/01/09/1372363.html
2,typedef和define的詳細區別,http://blog.csdn.net/21aspnet/article/details/6723915
以下均為轉載,僅供自己學習收藏之用!
一,typedef的用法總結
1,typedef的語法描述
在現實生活中,信息的概念可能是長度,數量和面積等。在C語言中,信息被抽象為int、float和 double等基本數據類型。從基本數據類型名稱上,不能夠看出其所代表的物理屬性,並且int、float和double為系統關鍵字,不可以修改。為了解決用戶自定義數據類型名稱的需求,C/C++語言中引入類型重定義語句typedef,可以為數據類型定義新的類型名稱,從而豐富數據類型所包含的屬性信息,typedef可以增強程序的可讀性,以及標識符的靈活性。
typedef的語法描述
typedef <類型名稱> <類型標識符>;
typedef為系統保留字(關鍵字),“類型名稱”為已知數據類型名稱,包括基本數據類型和用戶自定義數據類型,“類型標識符”為新的類型名稱。例如:
typedef double LENGTH;
typedef unsigned int COUNT;
定義新的類型名稱之后,可像基本數據類型那樣定義變量。例如:
typedef unsigned int COUNT;
unsigned int b;
COUNT c;
********************************************************************************************
2,typedef 的主要應用形式
typedef 的主要應用有如下的幾種形式:
1) 為基本數據類型定義新的類型名。
2) 為自定義數據類型(結構體、公用體和枚舉類型)定義簡潔的類型名稱。
3) 為數組定義簡潔的類型名稱。
4) 為指針定義簡潔的名稱。
*********************************************************************************************
2.1,為基本數據類型定義新的類型名:
定義一種類型的別名,而不只是簡單的宏替換。可以用作同時聲明指針型的多個對象。比如:
char* pa, pb;
// 這多數不符合我們的意圖,它只聲明了一個指向字符變量的指針,
// 和一個字符變量;
以下則可行:
typedef char* PCHAR;
PCHAR pa, pb;
這種用法很有用,特別是char* pa, pb的定義,初學者往往認為是定義了兩個字符型指針,其實不是,而用typedef char* PCHAR就不會出現這樣的問題,減少了錯誤的發生。
****************************************************************************
2.2,為自定義數據類型(結構體、公用體和枚舉類型)定義簡潔的類型名稱
用在舊的C代碼中,幫助struct。以前的代碼中,聲明struct新對象時,必須要帶上struct,即形式為: struct 結構名對象名,如:
2.3,用typedef來定義與平台無關的類型。
比如定義一個叫 REAL 的浮點類型,在目標平台一上,讓它表示最高精度的類型為:
typedef long double REAL;
在不支持 long double 的平台二上,改為:
typedef double REAL;
在連 double 都不支持的平台三上,改為:
typedef float REAL;
也就是說,當跨平台時,只要改下 typedef 本身就行,不用對其他源碼做任何修改。
標准庫就廣泛使用了這個技巧,比如size_t。另外,因為typedef是定義了一種類型的新別名,不是簡單的字符串替換,所以它比宏來得穩健。這個優點在我們寫代碼的過程中可以減少不少代碼量哦!
********************************************************************************
2.4,為復雜的聲明定義一個新的簡單的別名。(這個很重要)
方法是:在原來的聲明里逐步用別名替換一部分復雜聲明,如此循環,把帶變量名的部分留到最后替換,得到的就是原聲明的最簡化版。
舉例:
原聲明: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;
理解復雜聲明可用的“右左法則”:從變量名看起,先往右,再往左,碰到一個圓括號
就調轉閱讀的方向;括號內分析完就跳出括號,還是按先右后左的順序,如此循環,直
到整個聲明分析完。
舉例1:
int (*func)(int *p);
首先找到變量名func,外面有一對圓括號,而且左邊是一個*號,這說明func是一個指針;然后跳出這個圓括號,先看右邊,又遇到圓括號,這說明(*func)是一個函數,所以func是一個指向這類函數的指針,即函數指針,這類函數具有int*類型的形參,返回值類型是int。
舉例2:
int (*func[5])(int *);
func右邊是一個[]運算符,說明func是具有5個元素的數組;func的左邊有一個*,說明func的元素是指針(注意這里的*不是修飾func,而是修飾func[5]的,原因是[]運算符優先級比*高,func先跟[]結合)。跳出這個括號,看右邊,又遇到圓括號,說明func數組的元素是函數類型的指針,它指向的函數具有int*類型的形參,返回值類型為int。這種用法是比較復雜的,出現的頻率也不少,往往在看到這樣的用法卻不能理解,相信以上的解釋能有所幫助。
舉例3:
(此例子來源於孫鑫vc++,和例子1接近)
typedef int (*ADDPROC)(int a,int b)
typedef定義了一個函數指針類型,ADDPROC,它所表示的函數有兩個int類型的參數並且該函數的返回類型也是int類型,這里的ADDPROC是一個函數指針類型,不是一個變量!
代碼示例
二,typedef與define的區別
1,#define是預處理指令,在編譯預處理時進行簡單的替換,不作正確性檢查,不關含義是否正確照樣帶入,只有在編譯已被展開的源程序時才會發現可能的錯誤並報錯。例如:#define PI 3.1415926
程序中的:area=PI*r*r 會替換為3.1415926*r*r
如果你把#define語句中的數字9 寫成字母g 預處理也照樣帶入。
2,typedef是在編譯時處理的。它在自己的作用域內給一個已經存在的類型一個別名,但是You cannot use the typedef specifier inside a function definition。
3,typedef int * int_ptr;與#define int_ptr int *
作用都是用int_ptr代表 int * ,但是二者不同,正如前面所說 ,#define在預處理時進行簡單的替換,而typedef不是簡單替換 ,而是采用如同定義變量的方法那樣來聲明一種類型。也就是說;
-
<span style= "font-family:Times New Roman;font-size:18px;">
-
int_ptr a, b; //相當於int * a, b; 只是簡單的宏替換
-
-
typedef int* int_ptr;
-
int_ptr a, b; //a, b 都為指向int的指針,typedef為int* 引入了一個新的助記符</span>
-