C和C++中typedef的用法分析

 

   在代碼之中使用typedef聲明有助於創建與平臺無關的類型,隱藏C和C++語言中複雜和難以理解的符合類型,創造更爲美觀的代碼。

但是typedef的使用卻有一些很容易混淆的地方,簡單的用法還可以,稍微複雜一些的用法我就搞不懂了。在網上搜了一些資料,

看了看,自己總結了一下。

 

一、譚浩強版的用typedef定義已有的類型名的別名的步驟如下:

  (1)先按定義變量的方法寫出定義體;

  (2)將變量名換成新類型名;

  (3)在最前面加typedef;

  (4)之後就可以用新類型名去定義變量。

二、typedef用法

  1、最簡單的用法

  如:typedef int myint;

  myint  sn;  //相當於int  sn;

  是將myint作爲int類型的同義詞。

 

2、用typedef定義複合類型數組類型的同義詞

  如例所示typedef char  WORD[20];

  WORD  w1, w2; //相當於char  w1[20]; char  w2[20];

  則WORD就成了包含20個元素的char數組類型的同義詞。

 

3、用typedef定義簡單的複合的指針類型同義詞

  先看C和C++中指針類型糾結的定義。

  char*   pa,  pb;

  char    *pc, *pd;

  其中pa是char指針類型而pb不是,這多半不符合我們的常規理解方式,如果想要定義兩個char指針,則必須像定義pc和pd那樣;而且*的位置沒有影響。

但是利用typedef我們卻可以定義char*這種複合類型的同義詞。如下所示:

  typedef char * chPointer;

  chPointer  pi, po;這樣pi和po都是char指針類型了。

這裏還有一些需要注意的地方。如下:

  有函數int myStrcmp(const  char*, const  char*) ;

  如果定義Typedef  char* pStr;而且聲明myStrcmp()如下:

  int myStrcmp(const  pStr, const  pStr),那麼這將是錯誤的。因爲函數原型中的參數是指向char常量的指針,而聲明的卻是指向char的指針常量。

對於這一點我想必須要理解typedef不只是簡單的宏替換。應該從它所表示的意義上去理解。Typedef  char* pStr定義的是一個指向char的指針,

所以const pStr中const修飾的是一個指針,也就是說const pStr 表示的是一個char型指針常量。

 

要解決不一致的問題可以這樣:typedef const char*  pStr;這樣聲明函數就變成了:

int myStrcmp(pStr, pStr);

 

4、typedef用於struct的用法

  在舊的C的代碼中聲明struct新對象時,必須要帶上struct,即形式爲:

  struct 結構名 對象名,如:

  struct POINT

  {

  int  px;

  int  py;

  };

  struct POINT pot;

  而在C++中,則可以直接寫:結構名 對象名,即:POINT pot;

  爲了在C代碼的結構體聲明中少寫一個struct是代碼更爲緊湊和簡約,就有了如下的聲明方法:

  typedef struct POINT

  {

  int px;

  int py;

  }POINT;

 

這樣的一段代碼實際上做了兩件事情:

  (1)

  struct POINT

  {

  int px;

  int py;

  };

  (2)

  typedef struct POINT POINT;

以後就可以這樣聲明struct POINT類型的變量了:POINT pot;顯得簡約一點。

 

5、typedef隱藏複雜類型的用法

此種用法主要體現在定義函數型的指針上。關鍵點在於根據運算符的結合性,逐步理解其所代表的意義。

(1) 先看C語言中關於函數的聲明

  int Function(int ,char);

  其對應的函數指針聲明爲:int (*Fp) (int,char);

  當進行賦值時可以有以下形式:

  Fp = &Function;函數調用時的形式爲:(*Fp)(int, char)。

  Fp =  Function; 函數調用時的形式爲:  Fp(int, char)。

 

(2)再看C語言中關於數組的聲明

  int SN[6];

  其對應的數組指針聲明爲int (*pS)[6];注意括號的使用,因爲[]的優先級大於*。

  使用方式爲:pS = &SN; int a = (*pS)[0]。

 

(3)再看以下三個變量聲明

  #1    int* (*A[6])(char*,int*);

  #2    void (*B[6])(int(*)());

  #3    int(*)() (*P)[6];

然後再來分析以上聲明所代表的意義。

 

  #1

  int* (*A[6])(char*,int*);

  首先看變量名A,因爲[]的結合性大於*,所以A首先是一個數組,然後每個數組元素都是一個指針;再看括號外邊是一個函數的聲明形式,所以A數組中的每一個元素都是指向函數的指針。這種函數返回值爲int*型,參數形式爲(char*,int*)。

  用typedef來簡化此種類型聲明:

  typedef  int* (*pA)(char*, int*);

  pA  A[6];同int* (*A[6])(char*,int*);

 

  #2

  void (*B[6])(int(*)());

  類似於#1,B是一個數組,每個元素是一個指針,這個指針指向一個函數,函數的返回值爲void,參數爲int(*)()(也就是一個函數,返回值爲int無參數)。

用typedef來簡化此種類型聲明:

  typedef  void (*pB)(int (*)() );

  pB  B[6];同void (*B[6])(int(*)());

當然還可以逐步簡化:

  typedef  int (*pi) ();簡化指針指向的函數的參數;

  typedef  void (*pB)(pi);

  pB  B[6];同void (*B[6])(int(*)())。

 

#3

  int(*)() (*P)[6];

  首先P是一個指針,P指向了一個數組,這個數組的每一個元素爲指向函數的指針,指向的函數類型是返回值爲int無參數。

用typedef來簡化此種類型聲明:

  typedef int(*pi)();簡化數組的元素定義;

  typedef pi (*PP)[6];

  PP  P;同int(*)() (*P)[6];

 

(4)2個模式:
  type (*)(....) 函數指針                     type (*)[]   數組指針

 

關鍵還在於根據運算符的結合性,理解typedef定義的類型的意義,C語言在很多類似的地方都讓人糾結。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章