使用typedef定義函式指標

2021-06-28 20:42:29 字數 4233 閱讀 2607

關於c++中函式指標的使用(包含對typedef用法的討論) 

(一)簡單的函式指標的應用。

//形式1:返回型別(*函式名)(參數列) 

char (*pfun)(int); 

char glfun(int a)

void main() 

第一行定義了乙個指標變數pfun。首先我們根據前面提到的「形式1」認識到它是乙個指向某種函式的指標,這種函式引數是乙個int型,返回值是char型別。只有第一句我們還無法使用這個指標,因為我們還未對它進行賦值。

第二行定義了乙個函式glfun()。該函式正好是乙個以int為引數返回char的函式。我們要從指標的層次上理解函式——函式的函式名實際上就是乙個指標,函式名指向該函式的**在記憶體中的首位址

然後就是main()函式了,它的第一句您應該看得懂了——它將函式glfun的位址賦值給變數pfun。main()函式的第二句中「*pfun」顯然是取pfun所指向位址的內容,當然也就是取出了函式glfun()的內容,然後給定引數為2。

(二)使用typedef更直觀更方便。

//形式2:typedef 返回型別(*新型別)(參數列)

typedef char (*ptrfun)(int); 

ptrfun pfun;

char glfun(int a)

void main() 

typedef的功能是定義新的型別。第一句就是定義了一種ptrfun的型別,並定義這種型別為指向某種函式的指標,這種函式以乙個int為引數並返回char型別。後面就可以像使用int,char一樣使用ptrfun了。

第二行的**便使用這個新型別定義了變數pfun,此時就可以像使用形式1一樣使用這個變數了。

三)在c++類中使用函式指標。

//形式3:typedef 返回型別(類名::*新型別)(參數列) 

class ca

};

ca ca;

typedef char (ca::*ptrfun)(int); 

ptrfun pfun; 

void main() 

在這裡,指標的定義與使用都加上了「類限制」或「物件」,用來指明指標指向的函式是那個類的這裡的類物件也可以是使用new得到的。比如: 

ca *pca = new ca; 

pca->(*pfun)(2); 

delete pca;

而且這個類物件指標可以是類內部成員變數,你甚至可以使用this指標。比如:

類ca有成員變數ptrfun m_pfun; 

void ca::lcfun2() 

一句話,使用類成員函式指標必須有「->*」或「.*」的呼叫。

typedef作為型別定義關鍵字,用於在原有資料型別(包括基本型別、構造型別和指標等)的基礎上,由使用者自定義新的型別名稱。

在程式設計中使用typedef的好處,除了為變數取乙個簡單易記且意義明確的新名稱之外,還可以簡化一些比較複雜的型別宣告。比如:

typedef int int32;

將int32定義為與int具有相同意義的名字,這樣型別int32就可用於型別宣告和型別轉換了,它和型別int完全相同。比如:             

int32      a;                            // 定義整型變數a 

(int32)    b;                            // 將其它的型別b轉換為整型

既然已經有了int這個名稱,為什麼還要再取乙個名稱呢?主要是為了提高程式的可移植性。比如,某種微處理器的int為16位,long為32位。如果要將該程式移植到另一種體系結構的微處理器,假設編譯器的int為32位,long為64位,而只有short才是16位的,因此必須將程式中的int全部替換為short,long全部替換為int,如此這樣修改勢必工作量巨大且容易出錯。如果將它取乙個新的名稱,然後在程式中全部用新取的名稱,那麼要移植的工作僅僅只是修改定義這些新名稱即可。也就是說,只需要將以前的:

typedef int int16;

typedef long int32;

替換成:

typedef short int16;

typedef int int32;

由此可見,typedef宣告並沒有建立乙個新型別,而是為某個已經存在的型別增加乙個新的名字而已。用這種方式宣告的變數與通過宣告方式宣告的變數具有完全相同的屬性。

至於typedef如何簡化複雜的型別宣告,將在後續的章節中詳細闡述。

綜上所述,如果在變數定義的前面加上typedef,即可定義該變數的型別。比如:

int size;   這裡定義了乙個整型變數size,當加上typedef後:

typedef int size;

那麼,size就成為了上面的size變數的型別,即int型別。既然size是乙個型別,當然可以用它來定義另外乙個變數。即:

size a;

類似於變數的型別定義,也可以用typedef宣告新的型別,比如:

char              *ptr_to_char;            // 宣告ptr_to_char為乙個指向字元的指標

typedef  char     ptr_to_char;             // 宣告ptr_to_char為指向char的指標型別

ptr_to_char       pch;                    // 宣告pch是乙個指向字元的指標

對於初學者來說,也許會產生乙個這樣的疑問,為什麼不使用#define建立新的型別名?比如:

#define  ptr_to_char  char*

ptr_to_char           pch1, pch2;

由於有了「#define ptr_to_char char*」,因此「ptr_to_char pch1, pch2」可以展開為

char   *pch1, pch2;

所以pch2為char型變數。如果用typedef來定義的話,其**如下:

typedef  char*   ptr_to_char;

ptr_to_char      pch1, pch2;

則「ptr_to_char pch1, pch2」等價於

char   *pch1;

char   *pch2;

因此,pch1、pch2都是指標。

雖然#define語句看起來象typedef,但實際上卻有本質上的差別。對於#define來說,僅在編譯前對源**進行了字串替換處理;而對於typedef來說,它建立了乙個新的資料型別別名。由此可見,只是將pch1定義為指標變數,卻並沒有實現程式設計師的意圖,而是將pch2定義成了char型變數。

在指標函式中,有這樣一類函式,它們也返回指標,但是這個指標不是指向int、char之類的基本型別,而是指向函式。對於初學者,別說寫出這樣的函式宣告,就是看到這樣的寫法也是一頭霧水。比如,下面的語句:

int (*ff(int))(int *, int);

我們用上面介紹的方法分析一下,ff首先與後面的「()」結合,即:

int (*(ff(int)))(int *, int);                   // 用括號將ff(int)再括起來

也就意味著,ff是乙個函式。

接著與前面的「*」結合,說明ff函式的返回值是乙個指標。然後再與後面的「()」結合,也就是說,該指標指向的是乙個函式。

這種寫法確實讓人非常難懂,以至於一些初學者產生誤解,認為寫出別人看不懂的**才能顯示自己水平高。而事實上恰好相反,能否寫出通俗易懂的**是衡量程式設計師是否優秀的標準。一般來說,用typedef關鍵字會使該宣告更簡單易懂。在前面我們已經見過:

int (*pf)(int *, int);

也就是說,pf是乙個函式指標「變數」。當使用typedef宣告後,則pf就成為了乙個函式指標「型別」,即:

typedef int (*pf)(int *, int);

這樣就定義了返回值的型別。然後,再用pf作為返回值來宣告函式:

pf ff(int);

使用typedef定義函式指標

形式1 返回型別 函式名 參數列 cpp view plain copy char pfun int char glfun inta void main 第一行定義了乙個指標變數pfun。首先我們根據前面提到的 形式1 認識到它是乙個指向某種函式的指標,這種函式引數是乙個int型,返回值是char型...

typedef 定義函式指標

typedef 返回型別 新型別 參數列 typedef char ptrfun int ptrfun pfun char glfun int a void main typedef的功能是定義新的型別。第一句就是定義了一種ptrfun的型別,並定義這種型別為指向某種函式的指標,這種函式以乙個int...

C 使用 typedef 簡化函式指標定義

函式型別由返回型別和引數列表決定,與函式名無關 pf 指向乙個返回bool,且有兩個const string 型別引數的函式,pf 必須用括號括起來,否則會變成函式宣告 bool pf const string const string 由於函式指標型別容易變得笨拙,因此用 typedef 關鍵字簡...