我們知道C的整個編譯過程由預(yù)處理悼沈,編譯,鏈接三個步驟組成姐扮。include
命令是在預(yù)處理階段解析的絮供。而
預(yù)處理階段只是進(jìn)行簡單的文本替換
我們先來看看一個簡單的預(yù)處理過程
main.c
int main()
{
#if 1
int a=1;
int b=2;
int sum = a + b;
#endif
return (1+2);
}
對main.c文件進(jìn)行預(yù)處理 gcc -E main.c -o main.i
# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
int main()
{
//對應(yīng) main.c 文件此行應(yīng)該是 #if 1,現(xiàn)在已用空行 替換
int a=1;
int b=2;
int sum = a + b;
//對應(yīng) main.c 文件此行應(yīng)該是 #endif 現(xiàn)在已用空行替換
return (1+2);
}
我們對main.c文件稍加改動
main.c
int main()
{
#if 0 //!!!!!!!!!!!
int a=1;
int b=2;
int sum = a + b;
#endif
return (1+2);
}
我們利用if
宏使得三行代碼無效,我們再來看看預(yù)處理的結(jié)果
# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
int main()
{
//我們可以看到茶敏,預(yù)處理只是將這段無效代碼用空行替換
return (1+2);
}
其實壤靶,預(yù)處理階段只是進(jìn)行簡單的文本替換
一般情況下我們通過頭文件來定義外部接口,然后通過include
宏來引用睡榆。這里我們有一個例子
add.h
int notice
#ifndef ADD_H__
#define ADD_H__
int add(int a,int b);
int test = 100萍肆;
#endif
add.c
int add(int a,int b)
{
return (a+b);
}
main.c
#include "add.h"
int main()
{
return add(1,1);
}
對main.c文件進(jìn)行預(yù)處理 gcc -E main.c -o main.i
main.i
# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 1 "add.h" 1
int notice; //頭文件add.h里面的內(nèi)容
//ifndef等宏命令袍榆,現(xiàn)在已經(jīng)以空行替換
int add(int a,int b);
int test = 100;
# 2 "main.c" 2
int main()
{
return add(1,2);
}
我們可以看到我們通過include
引入了add.h
里面的內(nèi)容到main.c
頭文件里有下面幾行
#ifndef ...
#define ...
.....
#endif
是用來防止頭文件重復(fù)包含的
現(xiàn)在我們再來看一下
main.c
#include "add.h"
#include "add.h"
int main()
{
預(yù)處理后的結(jié)果
main.i
# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 1 "add.h" 1
int notice; //頭文件add.h里面的內(nèi)容
//ifndef等宏命令胀屿,現(xiàn)在已經(jīng)以空行替換
int add(int a,int b);
int test = 100;
# 2 "main.c" 2
# 1 "add.h" 1
int notice; //此處在ifndef等宏命令之前,所以被復(fù)制過來了包雀,我們可以看到宿崭,因為此時ADD_H__已經(jīng)被定義,所以內(nèi)容以空替換
# 3 "main.c" 2
int main()
{
return add(1,2);
}
另外我們可以發(fā)現(xiàn)才写,notice變量被重定義了葡兑。
所以include
命令會無條件的引入文本文件,但是我們可以通過
#ifndef ...
#define ...
.....
#endif
方法防止文件里面的內(nèi)容被重新包含(復(fù)制)赞草。
預(yù)處理階段只是進(jìn)行簡單的文本替換,而有了這幾種宏命令讹堤,我們便可以更靈活的設(shè)置文件的包含過程。
預(yù)處理階段只是進(jìn)行簡單的文本替換 其實不完全對厨疙,但是對于我們理解一些簡單的宏命令是足夠的洲守。