萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 編程語言綜合 >> C++

C++

至今已遇到兩個typedef詭異的定義,因此決定下筆記之,以備後用。

  【typedef之const指針】

  【案例】

  typedef string * pstr;

  const pstr cpstr;

  問上述代碼中cpstr是一個怎樣的指針?

    【分析】

  很多朋友,包括我自己在剛接觸到時,第一反應是:cpstr被定義為一個指向const string對象的普通指針,原因很簡單,置換一下string*與pstr的位置就得到

  //這顯然就是一個指向const string對象的普通指針

  const string * cpstr;

  然而,事不如人願,cpstr的確切定義為:一個指向string類型的const指針。

  看到這個答案,相比不少朋友稍顯驚訝,我也如此,其中內因,且聽我慢慢道來。

  之所以出錯,在於我們“置換一下就好了”,“置換”這個詞不應該用在typedef,而該用在#define宏身上,typedef是定義了一個類型別名,定義的結果遵循任何正常定義的標准。那麼這個typedef到底是怎麼定義了一個const指針呢?

  首先分析

  const pstr cpstr;

  這段代碼定義了一個pstr類型的const cpstr,實際上就是

  pstr const cpstr;

  為了便於理解,就拿int定義來說

  //二者等價,前者是習慣用法,後者是標准規定

  const int ival = 0;

  int const ival = 0;

  既然理解了cpstr是一個const的pstr類型的對象,pstr是什麼呢?pstr是string*,因此這樣一來,就成了cpstr是一個const的string*類型的對象,也即cpstr是一個指向普通string的const指針。

  總結】

  本次誤解主要源於大家認為typedef等同於#define宏定義,以為簡單替換字符就可以了。實則不然。以後見到這樣的定義,最簡單的辦法就是從定義該變量的地方入手

  typedef string * pstr;

  const pstr cpstr;

  按步驟(熟練了就很快了)思考:

  ①cpstr是一個類型為 pstr 的常量

  ②pstr 是什麼?

  ③pstr 是 string*

  ④所以,cpstr是一個類型為 string* 的常量,也即 string *const cpstr

    【typedef之函數類型】

  【案例】

  typedef int FUNC (int);

  請問typedef定義了一個什麼類型?

  【分析】

  不要驚訝,就是這樣,它不是一個函數指針,也不是被我寫錯了。

  它定義了一個函數類型FUNC,這個函數類型要求一個int形參,返回一個int結果。

  【總結】

  FUNC TestFunc(FUNC F);

  FUNC的用法是有限制的,上述語句會導致編譯時錯誤。

  上述代碼使用了兩次FUNC,出錯的是第一個,也就是FUNC類型的函數返回類型是有錯的。

  FUNC是函數類型,在另一個函數中,函數類型變量只能夠用作另一個函數的形參,而不能是返回類型。

  FUNC用作形參時,編譯器會自動將其轉換為FUNC* /*函數指針*/,而編譯器不會將作為函數返回類型的FUNC進行轉換,因此會出現編譯時錯誤,可修正如下

  FUNC* TestFunc(FUNC F);

  聲明了一個函數TestFunc,該函數要求一個函數類型為FUNC的函數F作為形參,並返回一個FUNC類型的函數指針FUNC*

  【typedef與#define】

  【案例】

  typedef int* Tpi;

  #define int* Dpi;

  Tpi p1,p2;

  Dpi p3,p4;

  問上述代碼中定義的四個變量分別為什麼類型?

    【分析】

  區分p1,p2,p3,p4四個變量的類型,首先要理解typedef和#define宏的區別,typedef是給已有的類型取別名,而#define只是簡單的字符替換。於是上述代碼等同於

  int *p1,*p2;//typedef的作用

  int *p3,p4;//#define的作用

  也就是說p3被定義為了一個整型指針,而p4則只是整型。

  【總結】

  需要掌握typedef與#define的區別,以防這些細微的陷阱,為高質量代碼做好保障。

copyright © 萬盛學電腦網 all rights reserved