1樓:匿名使用者
define與const的概念:
巨集不僅可以用來代替常數值,還可以用來代替表示式,甚至是**段。巨集的功能很強大,但也容易出錯,所以其利弊大小頗有爭議。
用巨集來代表常數,好處是:
1. 讓**更簡潔明瞭
當然這有賴於你為巨集取乙個適當的名字。一般來說,巨集的名字更要注重有明確直觀的意義,有時寧可讓它長點。
2. 方便**的維護
對巨集的處理,在編譯過程中稱為「預處理」。也就是說在正式編譯前,編譯器必須先將**出現的巨集,用其相應的巨集值替換,這個過程有點你我在文字處理軟體中查詢替換。完成預處理後,所有原來的「pai」都成了立即數3.
1415926.所以在**中使用巨集表達常數,歸根結底還是使用了立即數,並沒有明確指定這個量的型別。這容易帶來一些問題。
常量定義的格式為: const 資料型別 常量名 = 常量值;
const float pai = 3.1415926; const的作用是指明這個量(pai)是常量,而非變數。
常量必須一開始就指定乙個值,然後在以後的**中,不允許改變pai的值。
如果乙個常量是整型,可以省略指出資料型別。
const k = 100; 相當於 const int k = 100;
反過來說,如果不指出資料型別,則編譯器將它當作整型。
const k = 1.234;
你想讓k等於乙個實型數,然而最終k的值其實是1。因為編譯器把它當成整型常量。
我們建議在定義變數時,明確指出型別,不管它是整型或其它型別。
const int i = 100;
const double di = 100.0;
2樓:力波鴻
首先,需要理解const和#define的本質性不同.
使用const的時候(比如const int var = 3;),var一來是有型別的,二來它只在程式執行時被讀取.
而使用#define的時候(比如#define var 3),var是作為要修改的文字,3是作文替換文字,最後整個替換過程由編譯器完成,在程式執行後沒有var而直接是3.
也就是說:
#define var_a 3
const int var_b = 3;
對於:int i = var_a + var_b;
在編譯時會被解析為 i = 3 + var_b;
綜上所述,
#define a b實際是讓**中所有a替換成b
使用#define一般情況下可以加快執行速度,但降低編譯生成exe的速度.
使用const一般情況下會降低執行速度(因為要不斷從記憶體中取這個常量),但提高編譯速度,因為少去了字串的匹配與替換
至於好處,除了const有型別說明外,其他要看你怎麼用它再算是不是好處...
3樓:匿名使用者
主要是有資料型別, 用的時候避免一些錯誤
c++ 中define(巨集定義) 各種用法(含特殊),小舉個例子,謝謝!
4樓:會飛的小兔子
1、define是巨集定義,程式在預處理階段將用define定義的內容進行了替換。因此在程式執行時,常量表中並沒有用define定義的常量,系統不為它分配記憶體。而const定義的常量,在程式執行時,存在常量表中,且系統為它分配記憶體。
2、define定義的常量,預處理時只是直接進行了替換,因此在編譯時不能進行資料型別檢驗。而const定義的常量,在編譯時進行嚴格的型別檢驗,可以避免出錯。
3、define定義表示式時要注意「邊緣效應」。
例如:#definen1+2;
floata=n/2.0;
按照常規做法,可能會認為結果是3/2=1.5;
但是實際上,結果應該為1+2/2.0=2.0;
若想要實現3/2,則#definen(1+2);
即為避免邊緣效應,一定要加括號。
擴充套件資料c++巨集定義
#define命令是c++語言中的乙個巨集定義命令,它用來將乙個識別符號定義為乙個字串,該識別符號被稱為巨集名,被定義的字串稱為替換文字。
1、簡單的巨集定義:
#define 《巨集名》 《字串》
例: #define pi 3.14159262、帶引數的巨集定義
#define 《巨集名》 (《參數列》) 《巨集體》
例: #define a(x) x
5樓:湖人總冠軍
1、define是巨集定義,在預處理階段,程式將替換define定義的內容,因此,當程式執行時,常量表中沒有用define定義的常量,系統不會為它分配記憶體,當程式執行時,const定義的常量存在於常量表中,並且系統為它分配記憶體。
2、define定義的常量,只在預處理期間直接替換,因此在編譯期間無法執行資料型別驗證,對於const定義的常量,在編譯時進行嚴格的型別檢查可以避免錯誤。
3、define定義表示式時要注意「邊緣效應」。
例如:#definen1+2;
floata=n/2.0;
按慣例,可認為結果為3/2=1.5;
但實際上,結果應該是1+2/2.0=2.0;
如果你想達到3/2,定義(1+2);
為了避免邊緣效應,必須加括號。
6樓:匿名使用者
1 無參巨集定義
無參巨集的巨集名後不帶引數。
其定義的一般形式為:
#define 識別符號 字串
其中的「#」表示這是一條預處理命令。凡是以「#」開頭的均為預處理命令。「define」為巨集定義命令。「識別符號」為所定義的巨集名。「字串」可以是常數、表示式、格式串等。
在前面介紹過的符號常量的定義就是一種無參巨集定義。此外,常對程式中反覆使用的表示式進行巨集定義。
例如:#define m (y*y+3*y)
它的作用是指定識別符號m來代替表示式(y*y+3*y)。在編寫源程式時,所有的(y*y+3*y)都可由m代替,而對源程式作編譯時,將先由預處理程式進行巨集代換,即用(y*y+3*y)表示式去置換所有的巨集名m,然後再進行編譯。
【例】#define m (y*y+3*y)
main()
上例程式中首先進行巨集定義,定義m來替代表示式(y*y+3*y),在s=3*m+4*m+5* m中作了巨集呼叫。在預處理時經巨集後該語句變為:
s=3*(y*y+3*y)+4*(y*y+3*y)+5*(y*y+3*y);
但要注意的是,在巨集定義中表示式(y*y+3*y)兩邊的括號不能少。否則會發生錯誤。如當作以下定義後:
#difine m y*y+3*y
在巨集時將得到下述語句:
s=3*y*y+3*y+4*y*y+3*y+5*y*y+3*y;
這相當於:
3y2+3y+4y2+3y+5y2+3y;
顯然與原題意要求不符。計算結果當然是錯誤的。因此在作巨集定義時必須十分注意。應保證在巨集代換之後不發生錯誤。
對於巨集定義還要說明以下幾點:
1) 巨集定義是用巨集名來表示乙個字串,在巨集時又以該字串取代巨集名,這只是一種簡單的代換,字串中可以含任何字元,可以是常數,也可以是表示式,預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被巨集後的源程式時發現。
2) 巨集定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。
3) 巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束。如要終止其作用域可使用# undef命令。
例如:#define pi 3.14159
main()
#undef pi
f1()
表示pi只在main函式中有效,在f1中無效。
4) 巨集名在源程式中若用引號括起來,則預處理程式不對其作巨集代換。
【例】#define ok 100
main()
上例中定義巨集名ok表示100,但在printf語句中ok被引號括起來,因此不作巨集代換。程式的執行結果為:ok這表示把「ok」當字串處理。
5) 巨集定義允許巢狀,在巨集定義的字串中可以使用已經定義的巨集名。在巨集時由預處理程式層層代換。
例如:#define pi 3.1415926
#define s pi*y*y /* pi是已定義的巨集名*/
對語句:
printf("%f",s);
在巨集代換後變為:
printf("%f",3.1415926*y*y);
6) 習慣上巨集名用大寫字母表示,以便於與變數區別。但也允許用小寫字母。
7) 可用巨集定義表示資料型別,使書寫方便。
例如:#define stu struct stu
在程式中可用stu作變數說明:
stu body[5],*p;
#define integer int
在程式中即可用integer作整型變數說明:
integer a,b;
應注意用巨集定義表示資料型別和用typedef定義資料說明符的區別。
巨集定義只是簡單的字串代換,是在預處理完成的,而typedef是在編譯時處理的,它不是作簡單的代換,而是對型別說明符重新命名。被命名的識別符號具有型別定義說明的功能。
請看下面的例子:
#define pin1 int *
typedef (int *) pin2;
從形式上看這兩者相似, 但在實際使用中卻不相同。
下面用pin1,pin2說明變數時就可以看出它們的區別:
pin1 a,b;在巨集代換後變成:
int *a,b;
表示a是指向整型的指標變數,而b是整型變數。
然而:pin2 a,b;
表示a,b都是指向整型的指標變數。因為pin2是乙個型別說明符。由這個例子可見,巨集定義雖然也可表示資料型別, 但畢竟是作字元代換。在使用時要分外小心,以避出錯。
8) 對「輸出格式」作巨集定義,可以減少書寫麻煩。
【例】中就採用了這種方法。
#define p printf
#define d "%d\n"
#define f "%f\n"
main()
2 帶參巨集定義
c++語言允許巨集帶有引數。在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數。
對帶引數的巨集,在呼叫中,不僅要巨集,而且要用實參去代換形參。
帶參巨集定義的一般形式為:
#define 巨集名(形參表) 字串
在字串中含有各個形參。
帶參巨集呼叫的一般形式為:
巨集名(實參表);
例如:#define m(y) y*y+3*y /*巨集定義*/
……k=m(5); /*巨集呼叫*/
……在巨集呼叫時,用實參5去代替形參y,經預處理巨集後的語句為:
k=5*5+3*5
【例】#define max(a,b) (a>b)?a:b
main()
上例程式的第一行進行帶參巨集定義,用巨集名max表示條件表示式(a>b)?a:b,形參a,b均出現在條件表示式中。
程式第七行max=max(x,y)為巨集呼叫,實參x,y,將代換形參a,b。巨集後該語句為:
max=(x>y)?x:y;
用於計算x,y中的大數。
對於帶參的巨集定義有以下問題需要說明:
1. 帶參巨集定義中,巨集名和形參表之間不能有空格出現。
例如把:
#define max(a,b) (a>b)?a:b
寫為:#define max (a,b) (a>b)?a:b
將被認為是無參巨集定義,巨集名max代表字串 (a,b) (a>b)?a:b。巨集時,巨集呼叫語句:
max=max(x,y);
將變為:
max=(a,b)(a>b)?a:b(x,y);
這顯然是錯誤的。
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
使用關鍵字const而不是define語句的好處有哪些
如果只是常量定義的話,沒有什麼區別 最多是const帶型別可以進行型別的限制,以及可以進行取地址操作提倡使用const變數而不用 define沒有聽說過提倡使用inline函式而不是 define倒是經常提 區覺越靜和 首先,需要理解const和 define的本質性不同.使用const的時候 比如...
c的override關鍵字什麼意思
override保留字表示當前函式重寫了基類的虛擬函式。在函式比較多的情況下可以提示讀者某個函式重寫了基類虛擬函式,表示這個虛擬函式是從基類繼承,不是派生類自己定義的 強制編譯器檢查某個函式是否重寫基類虛擬函式,如果沒有則報錯。在類的成員函式引數列表後面新增該關鍵字既可。override只是c 保留...
C中關鍵字ref和out的區別,c 中ref和out關鍵字的用法,以及有什麼不同,求大神解答,線上等
山東中公優就業 1 兩者都是按地址傳遞的,使用後都將改變原來引數的數值。2 ref可以把引數的數值傳遞進函式,但是out是要把引數清空,就是說你無法把一個數值從out傳遞進去的,out進去後,引數的數值為空,所以你必須初始化一次。這個就是兩個的區別,或者說就像有的說的,ref是有進有出,out是隻出...