A. 預編譯的編譯指令
預編譯指令指示了在程序正式編譯前就由編譯器進行的操作,可以放在程序中的任何位置。常見的預編譯指令有:
(1)#include 指令
該指令指示編譯器將xxx.xxx文件的全部內容插入此處。若用<>括起文件則在系統的INCLUDE目錄中尋找文件,若用 括起文件則在當前目錄中尋找文件。一般來說,該文件是後綴名為h或cpp的頭文件。
注意:<>不會在當前目錄下搜索頭文件,如果我們不用<>而用把頭文件名擴起,其意義為在先在當前目錄下搜索頭文件,再在系統默認目錄下搜索。
(2)#define指令
該指令有三種用法:
第一種是定義標識,標識有效范圍為整個程序,形如#define XXX,常與#if配合使用;
第二種是定義常數,如#define max 100,則max代表100(這種情況下使用const定義常數更好,原因見注1);
第三種是定義函數,如#define get_max(a, b) ((a)>(b)?(a):(b)) 則以後使用get_max(x,y)就可以得到x和y中較大的數(這種方法存在一些弊病,見注2)。
第四種是定義宏函數,如#define GEN_FUN(type) type max_##type(type a,type b){return a>b?a:b;} ,使用時,用GEN_FUN(int),則此處預編譯後就變成了 max_int(int a,int b){return a>b?a:b;},以後就可以使用max_int(x,y)就可以得到x和y中較大的數.比第三種,增加了類型的說明。
(3)#if、#else和#endif指令
這些指令一般這樣配合使用:
#if defined(標識) //如果定義了標識
要執行的指令
#else
要執行的指令
#endif
在頭文件中為了避免重復調用(比如說兩個頭文件互相包含對方),常採用這樣的結構:
#if !(defined XXX) //XXX為一個在你的程序中唯一的標識符,
//每個頭文件的標識符都不應相同。
//起標識符的常見方法是若頭文件名為abc.h
//則標識為abc_h
#define XXX
真正的內容,如函數聲明之類
#endif
注1:因為:const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查,而對後者只進行字元替換,沒有類型安全檢查,並且在字元替換時可能會產生意料不到的錯誤(邊際效應)。
注2:例如get_max(a++, b)時,a++會被執行多少次取決於a和b的大小!所以建議還是用內聯函數而不是這種方法提高速度。雖然有這樣的弊病,但這種方法的確非常靈活,因為a和b可以是各種數據類型。
注3:可以查看網路的預處理命令,編排的比較簡明。
B. #ifdef #ifndef 到底怎麼用
條件預編譯
#if, #ifdef, #ifndef, #else, #elif, #endif通過這6條預編譯指令可以簡單控制編譯器的行為,當文件被編譯時,可以使用這些命令來控制一些特定的行被編譯或不被編譯。
#if expression如果表達式為真,命令後邊的代碼被編譯。
#ifdef macro如果宏被使用#define 定義,命令後邊的代碼被編譯。
#ifndef macro如果宏沒有被使用#define 定義,命令後邊的代碼被編譯。
A few side notes: #elif 命令是一種縮略形式,它和」elseif」具有同樣的作用,你也可以在#if之後使用」defined」或者」!defined」來擴展功能。
下邊是一個例子:
#ifdef DEBUG
cout << "This is the test version, i=" << i << endl;
#else
cout << "This is the proction version!" << endl;
#endif你應該注意到,這個例子和在代碼中插入/刪除大量的」cout」語句相比,使調試變得更容易。
C. 什麼是預編譯 何時需要預編譯 mfc面試
預編譯,顧名思義,「預」表示是在真正編譯前做的工作,既然也包含「編譯」二字,那與一些演算法邏輯是分不開的。
對於預編譯,是以符號#開頭的,包含以下幾部分語法:
(1)#include
該指令將xxx.xxx文件的全部內容插入此處,通常文件是後綴名為"h"或"cpp"的頭文件。
若用<>括起文件則在系統的INCLUDE目錄中尋找文件
若用" "括起文件則在當前目錄中尋找文件。
(2)#define
該指令有以下幾種用法:
第一種是定義標識,標識有效范圍為整個程序,形如#define XXX,常與#if配合使用;
第二種是定義常數,如#define max 100,則max代表100。
第三種是定義"函數",如#define get_max(a, b) ((a)>(b)?(a):(b)) 則以後使用get_max(x,y)就可以得到x和y中較大的數。
第四種是定義"宏函數",如#define GEN_FUN(type) type max_##type(type a,type b){return a>b?a:b;} ,使用時,用GEN_FUN(int),則此處預編譯後就變成了 max_int(int a,int b){return a>b?a:b;},以後就可以使用max_int(x,y)就可以得到x和y中較大的數.比第三種,增加了類型的說明。
(3)#if、#else和#endif指令
這些指令一般這樣配合使用:
#if defined(標識) //如果定義了標識
要執行的指令
#else
要執行的指令
#endif
在頭文件中為了避免重復調用(比如說兩個頭文件互相包含對方),常採用這樣的結構:
#if !(defined XXX) //XXX為一個在你的程序中唯一的標識符,
//每個頭文件的標識符都不應相同。
//起標識符的常見方法是若頭文件名為"abc.h"
//則標識為"abc_h"
#define XXX
真正的內容,如函數聲明之類
#endif
D. c++ 頭文件中加入 #ifnodef #define #engif 有什麼用
你說的是C語言中的宏定義,也是預編譯指令
首先,你對宏定義的書寫有誤,#ifnodef應該是#ifndef,#engif應該是#endif
接下來我們說說這幾個宏定義的用法
#define:這個宏定義就是使用一個命名來替代另一個。比如#define age 5
那麼,在程序中,填入age,在預編譯的時候,編譯器就會自動將age替換成5,注意,這個是直接替換,所以如果#define X 3+1,那麼在程序中輸入5*X,編譯器就會將其替換成5*3+1,這種情況一般會這樣定義#define X (3+1)
#ifdef、#ifndef、#endif:一般#ifdef/#ifndef和#endif是成對出現的。
#ifdef顧名思義,就是如果定義了某個宏。比如
#ifdef age //如果之前有#define age value(這個是age對應的值),就執行下面的語句
//do something
#endif //執行語句到這里結束
#ifndef與#ifdef正相反,直譯是if not define,就是如果沒有定義某個宏,就執行if內的語句。如:
#ifndef age //如果之前沒有#define age value(這個是age對應的值),就執行下面的語句
//do something
#endif //執行語句到這里結束
E. include的用法
include是預編譯指令,include<reg52.h>的作用就是將52單片機的頭文件reg52.h嵌入源文件中。
預處理器發現 #include 指令後,就會尋找指令後面<>中的文件名,並把這個文件的內容包含到當前文件中。被包含文件中的文本將替換源代碼文件中的#include 指令, 就像把被包含文件中的全部內容鍵入到源文件中的這個位置一樣。
<reg52.h>表示調用了52或者51單片機的資源,也就是可以直接對單片機的相關寄存器與引腳進行操作,十分方便。
(5)預編譯指令用法擴展閱讀:
reg52.h中特殊位元組寄存器說明:
sfr P0 = 0x80; // P0口特殊寄存器定址位
sfr P1 = 0x90; // P1口特殊寄存器定址位
sfr P2 = 0xA0; // P2口特殊寄存器定址位
sfr P3 = 0xB0; // P3口特殊寄存器定址位
sfr PSW = 0xD0; //程序狀態字寄存器
sfr ACC = 0xE0; //累加器
sfr B = 0xF0; //B 特殊寄存器
sfr SP = 0x81; //堆棧指針寄存器
sfr DPL = 0x82; //數字指針(低位)
sfr DPH = 0x83; //數字指針(高位)
sfr PCON = 0x87; //電源控制寄存器
sfr TCON = 0x88; //定時器/計數器0和1控制
sfr TMOD = 0x89; //定時器/計數器0和1模式
sfr TL0 = 0x8A; //定時器/計數器0低8位寄存器
sfr TL1 = 0x8B; //定時器/計數器1低8位寄存器
sfr TH0 = 0x8C; //定時器/計數器0高8位寄存器
sfr TH1 = 0x8D; //定時器/計數器1高8位寄存器
sfr IE = 0xA8; //中斷允許寄存器
sfr IP = 0xB8; //中斷優先寄存器(低)
sfr SCON = 0x98; //串口控制寄存器
sfr SBUF = 0x9 9; //串口數據緩沖器