C C 之define用法小結

2021-07-12 07:32:57 字數 3248 閱讀 3718

1、define——(無引數巨集定義)用法

一般形式為:#define

識別符號 字串

(1)「#」表示其為預處理命令,凡是以「#」開頭的都是預處理命令;「define」為巨集定義命令;「識別符號」為所定義的巨集名;「字串」可以是常數、表示式、字串等。

(2)除了經常用到的如「#define maxnum 100」之外,還有其它多種靈活的用法,如「#define m (y*y+3*y)」,注意,的表示式中()是必須的,否則在進行如「2*m+2」的運算

時就會出現錯誤。

(3)末尾不需要分號(如果加分號,會連同分號一起代換)。

(4)define只是做簡單的文字替換。

(5)作用域為巨集定義開始,到源程式結束,終止定義域可用「#undef m」。

(6)巨集名如果以字串的形式被呼叫,則不做替換,如printf(「i m o」)。

(7)可以巢狀進行定義,如

#define pi 3.14

#define s pi*r*r

(8)習慣上把巨集名寫為大寫的,以區別普通的變數。

2、define和typedef的區別

define巨集定義是在預處理完成的,typedef實在編譯時處理的,typedef不是簡單的代換,而是對型別說明符的重新命名。

例如:#define p1 int*

typedef int* p2;

p1 a, b;//相當於int* a, b,此時a是int指標,b是int整數。

p2 a, b;//表示a和b都是int指標。

3、define(帶引數巨集定義)用法

一般形式為:#define 巨集名(形參) 字串

最長見的 #define max(a,b) (a>b)?a:b

(1)巨集名和形參之間不能有空格。如果上式寫為 #define max (a,b) (a>b)?a:b,則max就表示整個後面的部分了。

(2)帶參巨集定義的形參是不分配記憶體的。

(3) 在巨集定義中的形參是識別符號,而巨集呼叫中的實參可以是表示式。

#define sq(y) (y)*(y)

main()

上例中第一行為巨集定義,形參為y。程式第七行巨集呼叫中實參為a+1,是乙個表示式,在巨集展開時,用a+1代換y,再用(y)*(y) 代換sq,得到如下語句 :

sq=(a+1)*(a+1);

這與函式的呼叫是不同的,函式呼叫時要把實參表示式的值求出來再賦予形參。而巨集代換中對實參表示式不作計算直接地照原樣代換。

(4) 在巨集定義中,字串內的形參通常要用括號括起來以避免出錯。在上例中的巨集定義中(y)*(y)表示式的y都用括號括起來,因此結果是正確的。如果去掉括號,把程式改 為以下形式:

#define sq(y) y*y

main()

執行結果為:

input a number:3

sq=7

(5)define的多行定義

define可以替代多行的**,例如mfc中的巨集定義

#define macro(arg1, arg2) do while(0) /* (no trailing ; ) */

關鍵是要在每乙個換行的時候加上乙個"/"

4、define巨集和函式的區別

(1)巨集定義可以幫助我們防止出錯,提高**的可移植性和可讀性等。

看乙個例子,比較兩個數或者表示式大小,首先我們把它寫成巨集定義:

#define max( a, b) ( (a) > (b) (a) : (b) )

其次,把它用函式來實現:

int max( int a, int b)

很顯然,我們不會選擇用函式來完成這個任務,原因有兩個:

首先,函式呼叫會帶來額外的開銷,它需要開闢一片棧空間,記錄返回位址,將形參壓棧,從函式返回還要釋放堆疊。這種開銷不僅會降低**效率,

而且**量也會大大增加,而使用巨集定義則在**規模和速度方面都比函式更勝一籌;其次,函式的引數必須被宣告為一種特定的型別,所以它只能在

型別合適的表示式上使用,我們如果要比較兩個浮點型的大小,就不得不再寫乙個專門針對浮點型的比較函式。反之,上面的那個巨集定義可以用於整

形、長整形、單浮點型、雙浮點型以及其他任何可以用「>」操作符比較值大小的型別,也就是說,巨集是與型別無關的。

和使用函式相比,使用巨集的不利之處在於每次使用巨集時,乙份巨集定義**的拷貝都會插入到程式中。除非巨集非常短,否則使用巨集會大幅度增加程式的長

度。 還有一些任務根本無法用函式實現,但是用巨集定義卻很好實現。比如引數型別沒法作為引數傳遞給函式,但是可以把引數型別傳遞給帶參的巨集。

看下面的例子:

#define malloc(n, type) /

( (type *) malloc((n)* sizeof(type)))

利用這個巨集,我們就可以為任何型別分配一段我們指定的空間大小,並返回指向這段空間的指標。我們可以觀察一下這個巨集確切的工作過程:

int *ptr;

ptr = malloc ( 5, int );

將這巨集展開以後的結果:

ptr = (int *) malloc ( (5) * sizeof(int) );

這個例子是巨集定義的經典應用之一,完成了函式不能完成的功能,但是巨集定義也不能濫用,通常,如果相同的**需要出現在程式的幾個地方,更好的

方法是把它實現為乙個函式。

**長度

#define巨集:每次使用時,巨集**都被插入到程式中。除了非常小的巨集之外,程式的長度將大幅度增長

函式:函式**只出現於乙個地方:每次使用這個函式時,都呼叫那個地方的同乙份**

執行速度

#define巨集:更快

函式: 存在函式呼叫、返回的額外開銷

操作符優先順序

#define巨集:巨集引數的求值是在所有周圍表示式的上下文環境裡,除非它們加上括號,否則鄰近操作符的優先順序可能產生不可預料的結果。

函式:函式引數只在函式呼叫時求值一次,它的結果值傳遞給函式。表示式的求值結果更容易**。

引數求值

#define巨集:引數用於巨集定義時,每次都將重新求值,由於多次求值,具有***的引數可能會產生不可**的結果。

函式:引數在函式呼叫前只求值一次,在函式中多次使用引數並不會導致多次求值過程,引數的***並不會造成任何特殊問題。

引數型別

#define巨集:巨集與型別無關,只要引數的操作是合法的,它可以用於任何引數型別。

函式: 函式的引數是與型別有關係的,如果引數的型別不同,就需要使用不同的函式,即使它們執行的任務是相同的。

C C 之define用法小結

1 define 無引數巨集定義 用法 一般形式為 define 識別符號 字串 1 表示其為預處理命令,凡是以 開頭的都是預處理命令 define 為巨集定義命令 識別符號 為所定義的巨集名 字串 可以是常數 表示式 字串等。2 除了經常用到的如 define maxnum 100 之外,還有其它...

Linux c中define的用法小結

define的用法只是一種純粹的替換功能,巨集定義的替換是預處理器處理的替換。一 簡單的巨集定義用法 格式 define 識別符號 替換內容 替換的內容可以是數字,字元,字串,特殊字元和空格,後面是什麼內容就會替換成什麼內容。例如 define n 5 效果等同於 int array 5 int a...

C C 預處理之 define

define 是 c c 中的一條預處理指令,用在一行的開始表示乙個預處理指令的開始 一條預處理指令以回車作為結束符,而不是以分號,分號會被替換掉。define m 4 把 m 定義為 4 define max a,b a b a b 定義表示式,而不是定義函式。所有的 define 預處理都只是起...