預(yù)編譯(預(yù)處理include、define)
C語音的執(zhí)行流程
C語言執(zhí)行的流程:
- 編譯:形成目標(biāo)代碼(.obj)。
- 連接:將目標(biāo)代碼與C函數(shù)庫連接合并,形成最終的可執(zhí)行文件。
- 執(zhí)行。
預(yù)編譯(預(yù)處理),為編譯做準(zhǔn)備工作,完成代碼文本的替換工作。
頭文件告訴編譯器有這樣一個(gè)函數(shù),連接器負(fù)責(zé)找到這個(gè)函數(shù)的實(shí)現(xiàn),通過include引入。實(shí)現(xiàn)的話,在哪里都可以。類似于Android布局文件中的include標(biāo)簽。
一個(gè)簡單的例子:
創(chuàng)建text.txt文件:
printf("我被包含進(jìn)來了");
在主函數(shù)里面使用:
#include<stdio.h>
#include<stdlib.h>
void main(){
#include "text.txt"
system("pause");
}
實(shí)質(zhì)上會把include標(biāo)簽替換成我們自己的text.txt文件里面的內(nèi)容。
VS源碼的目錄:C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src
宏定義、宏替換
作用:
- 定義標(biāo)識。
- 定義常數(shù)(便于修改與閱讀)。
- 定義“宏函數(shù)”。
1、定義標(biāo)識
作用:
1、例如通過判斷一些標(biāo)識是否定義來判斷是否支持某種語法、平臺等等:
//表示支持C++語法
#ifdef __cplusplus
#endif // __cplusplus
//表示支持Android、Windows、蘋果平臺等等
#ifdef ANDROID
#endif // ANDROID
2、防止問價(jià)你重復(fù)引入:
舉個(gè)例子,我們有三個(gè)文件a.h、b.h、Test.cpp,分別如下:
這是a.h:
#include "b.h"
void a();
這是b.h:
#include "a.h"
void b();
最后Test.cpp里面引用了a.h
#include "a.h"
這樣,當(dāng)Test包含a的時(shí)候,a又會去包含b,b又會包含a,這樣就會造成循環(huán)包含。類似于Hibernate里面的SQL循環(huán)引用。最終會報(bào)如下錯誤:
fatal error C1014: 包含文件太多 : 深度 = 1024
通過宏定義判斷就可以解決這個(gè)問題:(b.h省略)
#if A_H
#include "b.h"
void a();
#endif
另外,新版本的時(shí)候通過#pragma once語句即可自動解決這個(gè)問題。
//該頭文件只被包含一次,編譯器自動處理循環(huán)包含問題
#pragma once
2、定義常熟,方便閱讀
一個(gè)簡單的例子:
#define MAX 100
void main(){
int i = 100;
if (i == MAX){
printf("哈哈");
}
system("pause");
}
3、定義“宏函數(shù)”。
實(shí)質(zhì)上就是一個(gè)替換的過程。
簡單實(shí)用例子:
#define LOG(FORMAT , ...) printf("info"); printf(##FORMAT , __VA_ARGS__);
LOG會有級別,于是進(jìn)一步升級:
#define LOG_I(FORMAT , ...) printf("info"); printf(##FORMAT , __VA_ARGS__);
#define LOG_E(FORMAT , ...) printf("error"); printf(##FORMAT , __VA_ARGS__);
進(jìn)一步簡化重復(fù)代碼,重復(fù)LEVEL日志級別:
#define LOG(LEVEL , FORMAT , ...) printf(##LEVEL); printf(##FORMAT , __VA_ARGS__);
#define LOG_I(FORMAT , ...) LOG("info" , ##FORMAT , __VA_ARGS__)
#define LOG_E(FORMAT , ...) LOG("error" , ##FORMAT , __VA_ARGS__)
在Android JNI開發(fā)的時(shí)候,我們打印一句日志是通過__android_log_print函數(shù)來實(shí)現(xiàn)的,因此我們可以通過宏定義簡化代碼:
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"jason",FORMAT,##__VA_ARGS__);
LOGI("%s","fix");
//替換
__android_log_print(ANDROID_LOG_INFO, "jason", "%s", "fix");
如果覺得我的文字對你有所幫助的話,歡迎關(guān)注我的公眾號:
我的群歡迎大家進(jìn)來探討各種技術(shù)與非技術(shù)的話題,有興趣的朋友們加我私人微信huannan88,我拉你進(jìn)群交(♂)流(♀)。