預處理命令
在接觸#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 }
運行結果: