預處理命令使用詳解----#if、#endif、#undef、#ifdef、#else、#elif


預處理命令

在接觸#if、#undef這類預處理指令前,大部分都都接觸過#define、#include等預處理命令,通俗來講預處理命令的作用就是在編譯和鏈接之前,對源文件進行一些文本方面的操作,比如文本替換、文件包含、刪除部分代碼等,這個過程叫做預處理(在編譯之前對源文件進行簡單加工

(#define是一種宏定義命令,是預處理命令的一種)

 

#include(文件包含命令)

#include的用法有兩種,尖括號<>和雙引號""

第一種----尖括號

#include <stdio.h>

 

第二種----雙引號

#include "stdio.h"

使用尖括號和雙引號的區別在於頭文件的搜索路徑

尖括號:編譯器會到系統路徑下查找頭文件

雙引號:編譯器會先在當前目錄下查找頭文件,如果沒有找到,再到系統路徑下查找

注意事項:

1、一個 #include 命令只能包含一個頭文件

2、同一個頭文件可以被多次引入,多次引入的效果和一次引入的效果相同,因為頭文件在代碼層面有防止重復引入的機制

3、頭文件包含允許嵌套

(頭文件只能包含變量和函數的聲明,不能包含定義,否則在多次引入時會引起重復定義錯誤) 

 

#define(宏定義命令)

格式:#define 標識符 字符串 

並不是所有情況下#define所定義的字符串都會被替換,有一種特殊情況:被替換的字符串在""內

代碼示例:

1 #include <stdio.h>
2 
3 #define MAX 10
4 
5 int main() 6 { 7     printf("MAX"); 8 }

還有需要注意的一點是,不管是在某個函數內,還是在所有函數之外(不太建議把#define寫在函數內),#define作用域都是從定義開始直到整個文件結尾(這一點和typedef就區別很大)

#define(宏定義)----由預處理器來處理

typedef----在編譯階段由編譯器處理

 

代碼示例:

 1 #include <stdio.h>
 2 
 3 void fun();  4 int main()  5 {  6     #define MAX int
 7 
 8     MAX a = 10;  9     printf("%d", a); 10  fun(); 11 } 12 
13 void fun() 14 { 15     MAX b = 10; 16     printf("%d", b); 17 }

 define與typedef作用域的的區別:

typedef

如果放在所有函數之外,它的作用域就是從它定義開始直到文件尾

如果放在某個函數內,它的作用域就是從它定義開始直到該函數結尾

#define

不管是在某個函數內,還是在所有函數之外,作用域都是從定義開始直到整個文件結尾不管是typedef還是define,其作用域都不會擴展到別的文件,即使是同一個程序的不同文件,也不能互相使用

這里說下題外話#define叫宏定義,但是在筆者的認識里對聲明和定義的理解是:聲明不分配內存,定義才分配內存,所以#define雖然名字里面有“定義”兩個字,但並不占存儲空間(為什么不叫宏聲明···)

總結:#define和聲明、定義都不同,宏定義不占內存空間,因為宏在預處理階段就會被替換掉,到了編譯的階段是沒有宏存在的,它在預編譯階段就被處理了

 

#undef 

上文提到#define的作用域是從它聲明開始到文件結尾,#undef就是取消之前的宏定義(也就是#define的標識符)

格式:#undef 標識符(注意:如果標識符當前沒有被定義成一個宏名稱,那么就會忽略該指令)

 1 #include <stdio.h>
 2 
 3 #define MAX 10
 4 int main()  5 {  6     printf("%d", MAX);  7 #undef MAX
 8 #define    MAX 20
 9     printf("%d", MAX); 10 }

 

#if(條件編譯)

#if的使用和if else的使用非常相似,一般使用格式如下

#if 整型常量表達式1
    程序段1
#elif 整型常量表達式2
    程序段2
#else
    程序段3
#endif

執行起來就是,如果整形常量表達式為真,則執行程序段1,否則繼續往后判斷依次類推(注意是整形常量表達式),最后#endif是#if的結束標志

代碼示例:

 1 #include "stdio.h"
 2 
 3 #define MAX 10
 4 int main()  5 {  6     printf("MAX = %d\n", MAX);  7 
 8 #if    MAX == 10
 9     printf("MAX已被定義\n"); 10 #else 
11     printf("MAX未被定義\n"); 12     #undef MAX
13     #define    MAX 20
14 #endif
15 
16 
17     printf("MAX = %d\n", MAX); 18 
19     return 0; 20 }

運行結果:

代碼稍加修改:

 1 #include "stdio.h"
 2 
 3 #define MAX 10
 4 int main()  5 {  6 #if    MAX == 1
 7     printf("MAX已被定義\n");  8 #else 
 9     printf("MAX未被定義\n"); 10     #undef MAX
11     #define    MAX 20
12 #endif
13 
14 
15     printf("MAX = %d\n", MAX); 16 
17     return 0; 18 }

運行結果:

#if命令要求判斷條件為整型常量表達式,也就是說表達式中不能包含變量,而且結果必須是整數;而if后面的表達式沒有限制,只要符合語法就行,這是#if和if的一個重要區別

 

#ifdef

#ifdef的作用是判斷某個宏是否定義,如果該宏已經定義則執行后面的代碼,一般使用格式如下

#ifdef  宏名
    程序段1
#else
    程序段2
#endif

它的意思是,如果該宏已被定義過,則對程序段1進行編譯,否則對程序段2進行編譯(這個和上面的#if一樣最后都需要#endif),上述格式也可以不用#else,這一點上和if else相同

代碼示例:

 

 1 #include <stdio.h>
 2 
 3 #define MAX 10
 4 int main()  5 {  6 #ifdef MAX  7     printf("MAX已被定義\n");  8 #else 
 9     printf("MAX未被定義\n"); 10     #undef MAX
11     #define    MAX 20
12 #endif
13 
14 
15     printf("MAX = %d\n", MAX); 16 
17     return 0; 18 }

 

#ifndef

#ifndef恰好和#ifdef相反

#ifndef 宏名
    程序段1 
#else 
    程序段2 
#endif

如果該宏未被定義,則對“程序段1”進行編譯,否則對“程序段2”進行編譯

 

代碼示例:

 1 #include <stdio.h>
 2 
 3 #define MAX 10
 4 int main()  5 {  6 #ifndef MAX  7     printf("MAX未被定義\n");  8 #else 
 9     printf("MAX已被定義\n"); 10     #undef MAX
11     #define    MAX 20
12 #endif
13 
14 
15     printf("MAX = %d\n", MAX); 16 
17     return 0; 18 }

 

#elif

#elif相當於if else語句中的else if()語句,需要注意的是該語句是#elif,而不是#elseif

代碼示例:

 1 #include <stdio.h>
 2 
 3 #define MAX 10
 4 int main()  5 {  6 #if MAX==0
 7     printf("MAX=0");  8 #elif MAX==10
 9     printf("MAX=10\n"); 10 #endif
11 
12     return 0; 13 }

 

#endif

#endif上面已經用過多次了,需要知道的就是#endif#if, #ifdef, #ifndef這些條件命令的結束標志.這里就不再贅述了

上面說了8種預處理命令,下面再補充一個預處理函數(注意是函數且該函數有返回值)

 

defined函數

defined函數的作用是判斷某個宏是否被定義,若該宏被定義則返回1,否則返回0,該函數經常與#if #elif #else配合使用,一般使用格式為:

defined 宏名

defined (宏名)----(個人建議,還是加上括號比較好)

上文提到有#ifdef、#ifndef來判斷宏名是否被定義,乍一看defined有點多余,其實不然,#ifdef和#ifndef僅能一次判斷一個宏名,而defined能做到一次判斷多個宏名

代碼示例:

 

 1 #include <stdio.h>
 2 
 3 #define MAX 10
 4 #define MIN 2
 5 #define AVE 6
 6 int main()  7 {  8 #if defined (MAX) && defined (MIN) && defined (AVE)
 9     printf("三個宏已全部定義\n"); 10 #elif MAX==10
11     printf("三個宏未全部定義\n"); 12 #endif
13 
14     return 0; 15 }

運行效果:


代碼稍加修改:

 1 #include <stdio.h>
 2 
 3 #define MAX 10
 4 #define MIN 2
 5 //#define AVE 6
 6 int main()
 7 {
 8 #if defined (MAX) && defined (MIN) && defined (AVE)
 9     printf("三個宏已全部定義\n");
10 #elif MAX==10
11     printf("三個宏未全部定義\n");
12 #endif
13 
14     return 0;
15 }

運行結果:

預處理功能是C語言特有的功能,使用預處理功能便於程序的修改、閱讀、移植和調試,也便於實現模塊化程序設計
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM