C++ Typedef和define的用法

Define

定義:

define,宏定義,C語言中預處理命令一種。分爲無參宏定義和帶參宏定義。

  1. 無參宏定義的一般形式爲:#define 宏名 字符串
  2. 帶參宏定義的一般形式爲:#define 宏名(參數表) 字符串

#define 命令是 C 語言中的一個宏定義命令 ,它用來將一個標識符定義爲一個字符串 , 該標識符被稱爲宏名, 被定義的字符串稱爲替換文本。 [1]  該命令有兩種格式:一種是簡單的宏定義, 另一種是帶參數的宏定義。

分類:

無參宏定義:

C語言中無參宏定義的一般形式爲:#define 宏名 字符串 

其中的“#”表示這是一條預處理命令。凡是以“#”開頭的均爲預處理命令。“define”爲宏定義命令。“標識符”爲所定義的宏名。“字符串”可以是常數、表達式、格式串等。

例如: 

#define M (a+b) 

它的作用是指定標識符M來代替表達式(a+b)。在編寫源程序時,所有的(a+b)都可由M代替,而對源程序作編譯時,將先由預處理程序進行宏代換,即用(a+b)表達式去置換所有的宏名M,然後再進行編譯。

有參宏定義:

C語言允許宏帶有參數。在宏定義中的參數稱爲形式參數,在宏調用中的參數稱爲實際參數。對帶參數的宏,在調用中,不僅要宏展開,而且要用實參去代換形參

帶參宏定義的一般形式爲:  #define 宏名(形參表)字符串 [2] 

在字符串中含有各個形參。 帶參宏調用的一般形式爲:  宏名(形參表)

例如:

#define M(y) ((y)*(y)+3*(y))

k=M*5

在宏調用時,用實參5去代替形參y,經預處理宏展開後的語句爲:  k=5*5+3*5

注意:

1.宏定義是用宏名來表示一個字符串,在宏展開時又以該字符串取代宏名,這只是一種簡單的代換,字符串中可以含任何字符,可以是常數,也可以是表達式,預處理程序對它不作任何檢查。如有錯誤,只能在編譯已被宏展開後的源程序時發現。

2.宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。

3.宏定義其作用域爲宏定義命令起到源程序結束。如要終止其作用域可使用#undef命令。

條件編譯:

一般情況下,源程序中所有的行都參加編譯,但是有時希望只對其中一部分內容在滿足一定條件時才進行編譯,這時就需要使用到一些條件編譯命令。而在#if條件編譯命令中,需要判斷符號常量所定義的具體值,但有時並不需要判斷具體值,只需要知道這個符號常量是否被定義了。這時就不需要使用#if,而採用#ifdef和#ifndef,分別表示“如果有定義”及“如果無定義”。同時,如果我們需要刪除事先定義的宏定義,可以使用#undef命令。 [2] 

#ifdef

如果有定義的#ifdef的一般形式爲:#ifdef 宏替換名 語句段 #endif

含義爲:如果宏替換名已被定義過,則對“語句段”進行編譯;如果未定義#ifdef後面的宏替換名,則不對語句段進行編譯。

#ifndef

如果無定義的#ifndef的一般形式爲:#ifndef 宏替換名 語句段 #endif

含義爲:如果未定義#ifndef後面的宏替換名,則對“語句段1”進行編譯;如果定義#ifndef後面的宏替換名,則不執行語句段。

#undef

#undef命令可以刪除事先定義了的宏定義。

#undef命令的一般形式如下:#undef 宏替換名

例子:

#define MAX_SIZE 100

char array[MAX_SIZE];

#undef   MAX_SIZE

上述代碼中,首先使用#define定義標識符MAX_SIZE,直到遇到#undef語句之前,MAX_SIZE的定義都是有效的。

說明:#undef的主要目的是將宏名侷限在僅需要它們的代碼段中。

 


 

Typedef

定義:

typedef是在計算機編程語言中用來爲複雜的聲明定義簡單的別名,它與宏定義有些差異。它本身是一種存儲類的關鍵字,與auto、extern、mutable、static、register等關鍵字不能出現在同一個表達式中。

用法:

使用typedef爲現有類型創建別名,定義易於記憶的類型名

typedef int size;

size len = file.getLength();

此處size代表int類型

typedef char Line[81];

Line line;

此處Line代表具有81個元素的字符數組

typedef char* pstr

int mystrcmp(const pstr pq,const pstr p3)

此處pstr代表指向字符類型變量的指針

typedef的特殊用法:

1.typedef與結構體結合使用

typedef struct tagMyStruct

{

int iNum;

long lLength;

}MyStruct;

分析:

tagMyStruct稱爲“tag”,即“標籤”,實際上是一個臨時名字,struct關鍵字和tagMyStruct一起,構成了這個結構類型,不論是否有typedef,這個結構都存在。

我們可以用struct tagMyStruct varName來定義變量,但要注意,使用tagMyStruct varName來定義變量是不對的,因爲struct 和tagMyStruct合在一起才能表示一個結構類型。

typedef爲這個新的結構起了一個名字,叫MyStruct。

typedef struct tagMyStruct MyStruct;

因此,MyStruct實際上相當於struct tagMyStruct,我們可以使用MyStruct varName來定義變量。

複雜的變量聲明

下面是三個變量的聲明,我想使用typdef分別給它們定義一個別名,請問該如何做?

int *(*a[5])(int, char*);

void (*b[10]) (void (*)());

double(* (*pa)[9])();

分析:

對複雜變量建立一個類型別名的方法很簡單,你只要在傳統的變量聲明表達式裏用類型名替代變量名,然後把關鍵字typedef加在該語句的開頭就行了。

1:int *(*a[5])(int, char*);

//pFun是我們建的一個類型別名

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

//使用定義的新類型來聲明對象,等價於int* (*a[5])(int, char*);

pFun a[5];

>2:void (*b[10]) (void (*)());

//首先爲上面表達式加粗部分聲明一個新類型

typedef void (*pFunParam)();

//整體聲明一個新類型

typedef void (*pFun)(pFunParam);

//使用定義的新類型來聲明對象,等價於void (*b[10]) (void (*)());

pFun b[10];

>3. double(* [1]  (*pa)[9])() [2]  ;

//首先爲上面表達式藍色部分聲明一個新類型

typedef double(*pFun)();

//整體聲明一個新類型

typedef pFun (*pFunParam)[9];

//使用定義的新類型來聲明對象,等價於double(*(*pa)[9])();

pFunParam pa;

pa是一個指針,指針指向一個數組,這個數組有9個元素,每一個元素都是“doube(*)()”--也即一個指針,指向一個函數,函數參數爲空,返回值是“double”。

 


 

Define和Typedef的區別:

typedef char* pStr1;

#define pStr2 char* 

pStr1 s1,s2;

pStr2 s3,s4;

在上述的變量定義中,s1、s2、s3都被定義爲char *,而s4則定義成了char,不是我們所預期的指針變量,根本原因就在於#define只是簡單的字符串替換而typedef則是爲一個類型起新名字。

上例中define語句必須寫成 pStr2 s3, *s4; 這樣才能正常執行。

#define宏定義有一個特別的長處:可以使用 #ifdef ,#ifndef等來進行邏輯判斷,還可以使用#undef來取消定義。

 typedef也有一個特別的長處:它符合範圍規則,使用typedef定義的變量類型其作用範圍限制在所定義的函數或者文件內(取決於此變量定義的位置),而宏定義則沒有這種特性。

 

主要資料來源百度百科:

  1. https://baike.baidu.com/item/typedef/9558154?fr=aladdin
  2. https://baike.baidu.com/item/define/577777?fr=aladdin
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章