Android NDK開發(fā)之旅8--C語言基礎(chǔ)--預(yù)編譯

預(yù)編譯(預(yù)處理include、define)

C語音的執(zhí)行流程

C語言執(zhí)行的流程:

  1. 編譯:形成目標(biāo)代碼(.obj)。
  2. 連接:將目標(biāo)代碼與C函數(shù)庫連接合并,形成最終的可執(zhí)行文件。
  3. 執(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

宏定義、宏替換

作用:

  1. 定義標(biāo)識。
  2. 定義常數(shù)(便于修改與閱讀)。
  3. 定義“宏函數(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)注我的公眾號:

公眾號:Android開發(fā)進(jìn)階

我的群歡迎大家進(jìn)來探討各種技術(shù)與非技術(shù)的話題,有興趣的朋友們加我私人微信huannan88,我拉你進(jìn)群交(♂)流(♀)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容