預(yù)編譯(預(yù)處理include猴凹、define)
C語音的執(zhí)行流程
C語言執(zhí)行的流程:
- 編譯:形成目標代碼(.obj)。
- 連接:將目標代碼與C函數(shù)庫連接合并夫否,形成最終的可執(zhí)行文件顷锰。
- 執(zhí)行。
預(yù)編譯(預(yù)處理)绰姻,為編譯做準備工作枉侧,完成代碼文本的替換工作。
頭文件告訴編譯器有這樣一個函數(shù)狂芋,連接器負責找到這個函數(shù)的實現(xiàn)榨馁,通過include引入。實現(xiàn)的話帜矾,在哪里都可以翼虫。類似于Android布局文件中的include標簽。
一個簡單的例子:
創(chuàng)建text.txt文件:
printf("我被包含進來了");
在主函數(shù)里面使用:
#include<stdio.h>
#include<stdlib.h>
void main(){
#include "text.txt"
system("pause");
}
實質(zhì)上會把include標簽替換成我們自己的text.txt文件里面的內(nèi)容屡萤。
VS源碼的目錄:C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src
宏定義珍剑、宏替換
作用:
- 定義標識。
- 定義常數(shù)(便于修改與閱讀)死陆。
- 定義“宏函數(shù)”招拙。
1、定義標識
作用:
1措译、例如通過判斷一些標識是否定義來判斷是否支持某種語法别凤、平臺等等:
//表示支持C++語法
#ifdef __cplusplus
#endif // __cplusplus
//表示支持Android、Windows领虹、蘋果平臺等等
#ifdef ANDROID
#endif // ANDROID
2规哪、防止問價你重復引入:
舉個例子,我們有三個文件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"
這樣,當Test包含a的時候均唉,a又會去包含b是晨,b又會包含a,這樣就會造成循環(huán)包含。類似于Hibernate里面的SQL循環(huán)引用。最終會報如下錯誤:
fatal error C1014: 包含文件太多 : 深度 = 1024
通過宏定義判斷就可以解決這個問題:(b.h省略)
#if A_H
#include "b.h"
void a();
#endif
另外咪橙,新版本的時候通過#pragma once語句即可自動解決這個問題。
//該頭文件只被包含一次箫章,編譯器自動處理循環(huán)包含問題
#pragma once
2、定義常熟镜会,方便閱讀
一個簡單的例子:
#define MAX 100
void main(){
int i = 100;
if (i == MAX){
printf("哈哈");
}
system("pause");
}
3檬寂、定義“宏函數(shù)”。
實質(zhì)上就是一個替換的過程戳表。
簡單實用例子:
#define LOG(FORMAT , ...) printf("info"); printf(##FORMAT , __VA_ARGS__);
LOG會有級別桶至,于是進一步升級:
#define LOG_I(FORMAT , ...) printf("info"); printf(##FORMAT , __VA_ARGS__);
#define LOG_E(FORMAT , ...) printf("error"); printf(##FORMAT , __VA_ARGS__);
進一步簡化重復代碼,重復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ā)的時候匾旭,我們打印一句日志是通過__android_log_print函數(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)注我的公眾號:
我的群歡迎大家進來探討各種技術(shù)與非技術(shù)的話題价涝,有興趣的朋友們加我私人微信huannan88女蜈,我拉你進群交(♂)流(♀)。