最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言 深入講解條件編譯的用處

 更新時(shí)間:2022年04月19日 11:29:15   作者:清風(fēng)自在 流水潺潺  
C語(yǔ)言提供了條件編譯的語(yǔ)法,就是在編譯源碼的時(shí)候,可以選擇性地編譯指定的代碼。例如我們開(kāi)發(fā)一個(gè)兼容windows系統(tǒng)和linux系統(tǒng)運(yùn)行的項(xiàng)目,那么,一些與操作系統(tǒng)密切相關(guān)的代碼,就需要進(jìn)行選擇性編譯

一、基本概念

  • 條件編譯的行為類似于 C 語(yǔ)言中的 if...else...
  • 編譯是預(yù)編譯指示命令,用于控制是否編譯某段代碼

下面看一段簡(jiǎn)單的條件編譯的代碼:

#include <stdio.h>
 
#define C 1
 
int main()
{
    const char* s;
 
    #if( C == 1 )
        s = "This is first printf...\n";
    #else
        s = "This is second printf...\n";
    #endif
 
    printf("%s", s);
    
    return 0;
}

下面為輸出結(jié)果:

可以輸入gcc -E Test.c -o file.i 命令,看看預(yù)編譯階段發(fā)生了什么,下面是部分輸出結(jié)果:

# 2 "Test.c" 2
 
int main()
{
    const char* s;
 
        s = "This is first printf...\n";
 
    printf("%s", s);
 
    return 0;
}

可以看到宏定義和條件編譯都沒(méi)有了,由相應(yīng)內(nèi)容取而代之。

二、條件編譯的本質(zhì)

預(yù)編譯器根據(jù)條件編譯指令有選擇的刪除代碼

編譯器不知道代碼分支的存在

if...else... 語(yǔ)句在運(yùn)行期進(jìn)行分支判斷

條件編譯指令在預(yù)編譯期進(jìn)行分支判斷

可以通過(guò)命令行定義宏

  • gcc -Dmacro=value file.c
  • gcc -Dmacro file.c

下面看一個(gè)通過(guò)命令行定義宏的代碼:

#include <stdio.h>
int main()
{
    const char* s;
 
    #ifdef C
        s = "This is first printf...\n";
    #else
        s = "This is second printf...\n";
    #endif
 
    printf("%s", s);
    
    return 0;
}

終端輸入gcc -DC Test.c,輸出結(jié)果如下:

三、#include 的本質(zhì)

  • #include 的本質(zhì)是將已經(jīng)存在的文件內(nèi)容嵌入到當(dāng)前文件中
  • #include 的間接包含同樣會(huì)產(chǎn)生嵌入文件內(nèi)容的操作

這就出現(xiàn)一個(gè)問(wèn)題,間接包含同一個(gè)頭文件是否會(huì)產(chǎn)生編譯錯(cuò)誤?

下面就來(lái)通過(guò)一段代碼深入探究:

global.h:

// global.h
int global = 10;

test.h:

// test.h
 
#include "global.h"
 
const char* NAME = "test.h";
 
char* hello_world()
{
    return "hello world!\n";
}

test.c:

#include <stdio.h>
#include "test.h"
#include "global.h"
int main()
{
    const char* s = hello_world();
    int g = global;
    
    printf("%s\n", NAME);
    printf("%d\n", g);
    
    return 0;
}

編譯后編譯器報(bào)錯(cuò),global 重定義:

為什么 global 會(huì)重定義呢?下面開(kāi)始單步編譯,輸入gcc -E test.c -o test.i,輸出部分結(jié)果如下:

# 2 "test.c" 2
# 1 "test.h" 1
 
 
# 1 "global.h" 1
 
 
int global = 10;
# 4 "test.h" 2
 
const char* NAME = "test.h";
 
char* hello_world()
{
    return "hello world!\n";
}
# 3 "test.c" 2
# 1 "global.h" 1
 
 
int global = 10;
# 4 "test.c" 2
 
int main()
{
    const char* s = hello_world();
    int g = global;
 
    printf("%s\n", NAME);
    printf("%d\n", g);
 
    return 0;
}

這樣就很明顯了,程序先將 test.h 里面的東西復(fù)制進(jìn) test.c,由于 test.h 里面有一個(gè) include "global.h",就把int global = 10; 復(fù)制過(guò)來(lái),然后復(fù)制

const char* NAME = "test.h";

char* hello_world()

{undefined

return "hello world!\n";

}

在然后由于test.c 里面又定義一個(gè)#include "global.h",又把int global = 10; 復(fù)制過(guò)來(lái),造成了重復(fù)定義。

條件編譯可以解決頭文件重復(fù)包含的編譯錯(cuò)誤

#ifndef _HEADER_FILE_H_
#define _HEADER_FILE_H_
//source code
#endif

如果沒(méi)有定義 header_file.h,則定義,且執(zhí)行里面的代碼;否則,如果定義了,里面的代碼就不會(huì)執(zhí)行。

所以上述代碼中可以這么改:

global.h:

// global.h
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
int global = 10;
 
#endif

test.h:

// test.h
#ifndef _TEST_H_
#define _TEST_H_
#include "global.h"
const char* NAME = "test.h";
char* hello_world()
{
    return "hello world!\n";
}
#endif

這樣編譯就能通過(guò)了

四、條件編譯的意義

條件編譯使得我們可以按不同的條件編譯不同的代碼段,因而可以產(chǎn)生不同的目標(biāo)代碼

#if...#else...#endif 被預(yù)編譯器處理,而 if...else... 語(yǔ)句被編譯器處理,必然被編譯進(jìn)目標(biāo)代碼

實(shí)際工程中條件編譯主要用于以下兩種情況:

  • 不同的產(chǎn)品線共用一份代碼
  • 區(qū)分編譯產(chǎn)品的調(diào)試版和發(fā)布版

下面看一段產(chǎn)品線區(qū)分及調(diào)試代碼:

product.h:

#define DEBUG 1
#define HIGH  1

test.c:

#include <stdio.h>
#include "product.h"
#if DEBUG
    #define LOG(s) printf("[%s:%d] %s\n", __FILE__, __LINE__, s)
#else
    #define LOG(s) NULL
#endif
#if HIGH
void f()
{
    printf("This is the high level product!\n");
}
#else
void f()
 
{
 
}
#endif
int main()
 
{
    LOG("Enter main() ..."); 
    f(); 
    printf("1. Query Information.\n");
    printf("2. Record Information.\n");
    printf("3. Delete Information.\n");
    #if HIGH
    printf("4. High Level Query.\n");
    printf("5. Mannul Service.\n");
    printf("6. Exit.\n");
    #else
    printf("4. Exit.\n");
    #endif
    LOG("Exit main() ...");
    return 0;
}

宏 DEBUG 是指產(chǎn)品是調(diào)試版還是發(fā)布版,調(diào)試版為 1,發(fā)布版為 0, 宏 HIGH指的是產(chǎn)品是高端產(chǎn)品還是低端產(chǎn)品,高端產(chǎn)品為 1,低端產(chǎn)品為 0

如果我們想測(cè)試調(diào)試版的高端產(chǎn)品,令 DEBUG 為 1,HIGH為 0 即可:

同理,我們想測(cè)試發(fā)布版的低端產(chǎn)品,令 DEBUG 為 0,HIGH為 0 即可:

五、小結(jié)

  • 通過(guò)編譯器命令行能夠定義預(yù)處理器使用的宏
  • 條件編譯可以避免重復(fù)包含頭同一個(gè)頭文件
  • 條件編譯是在I程開(kāi)發(fā)中可以區(qū)別不同產(chǎn)品線的代碼
  • 條件編譯可以定義產(chǎn)品的發(fā)布版和調(diào)試版

到此這篇關(guān)于C語(yǔ)言 深入講解條件編譯的用處的文章就介紹到這了,更多相關(guān)C語(yǔ)言 條件編譯內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)掃雷小游戲(擴(kuò)展版可選擇游戲難度)

    C語(yǔ)言實(shí)現(xiàn)掃雷小游戲(擴(kuò)展版可選擇游戲難度)

    游戲目標(biāo)是找出所有沒(méi)有地雷的方格,完成游戲;要是按了有地雷的方格,游戲失??;玩家可標(biāo)記雷的位置,游戲以完成時(shí)間來(lái)評(píng)高低,并且用戶可以選擇游戲難度
    2019-10-10
  • 隨機(jī)數(shù)字去掉重復(fù)和排序的方法

    隨機(jī)數(shù)字去掉重復(fù)和排序的方法

    用計(jì)算機(jī)隨機(jī)生成了N個(gè)0到1000000000(包含0和1000000000)之間的隨機(jī)整數(shù)(N≤5000000),對(duì)于其中重復(fù)的數(shù)字,只保留一個(gè),把其余相同的數(shù)去掉。然后再把這些數(shù)從小到大排序。
    2013-03-03
  • 解析C++ 浮點(diǎn)數(shù)的格式化顯示

    解析C++ 浮點(diǎn)數(shù)的格式化顯示

    本篇文章是對(duì)C++中浮點(diǎn)數(shù)的格式化顯示進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++實(shí)現(xiàn)迷宮算法實(shí)例解析

    C++實(shí)現(xiàn)迷宮算法實(shí)例解析

    這篇文章主要介紹了C++實(shí)現(xiàn)迷宮算法實(shí)例解析,是一個(gè)比較經(jīng)典的C++算法,有一定的學(xué)習(xí)與借鑒價(jià)值,需要的朋友可以參考下
    2014-07-07
  • C語(yǔ)言內(nèi)存泄漏常見(jiàn)情況及解決方案詳解

    C語(yǔ)言內(nèi)存泄漏常見(jiàn)情況及解決方案詳解

    這篇文章主要為大家介紹了C語(yǔ)言內(nèi)存泄漏常見(jiàn)情況及解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • C++基于EasyX實(shí)現(xiàn)簡(jiǎn)單掃雷游戲

    C++基于EasyX實(shí)現(xiàn)簡(jiǎn)單掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了C++基于EasyX實(shí)現(xiàn)簡(jiǎn)單掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 一文詳解C++中的轉(zhuǎn)換構(gòu)造函數(shù)

    一文詳解C++中的轉(zhuǎn)換構(gòu)造函數(shù)

    在 C/C++ 中,不同的數(shù)據(jù)類型之間可以相互轉(zhuǎn)換,無(wú)需用戶指明如何轉(zhuǎn)換的稱為自動(dòng)類型轉(zhuǎn)換(隱式類型轉(zhuǎn)換),需要用戶顯式地指明如何轉(zhuǎn)換的稱為強(qiáng)制類型轉(zhuǎn)換,本文就給大家詳細(xì)介紹一下C++的轉(zhuǎn)換構(gòu)造函數(shù),需要的朋友可以參考下
    2023-09-09
  • String底層函數(shù)的實(shí)現(xiàn)方式詳解

    String底層函數(shù)的實(shí)現(xiàn)方式詳解

    這篇文章主要介紹了String底層函數(shù)的實(shí)現(xiàn)方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 在C語(yǔ)言編程中使用變量的基礎(chǔ)教程

    在C語(yǔ)言編程中使用變量的基礎(chǔ)教程

    這篇文章主要介紹了在C語(yǔ)言編程中使用變量的基礎(chǔ)教程,特別需要注意C語(yǔ)言中的指針變量,需要的朋友可以參考下
    2016-02-02
  • C語(yǔ)言文件打開(kāi)的模式

    C語(yǔ)言文件打開(kāi)的模式

    這篇文章主要介紹了C語(yǔ)言文件打開(kāi)的模式,以及相關(guān)的原理和知識(shí)點(diǎn)做了分享,有興趣的朋友參考學(xué)習(xí)下。
    2018-03-03

最新評(píng)論

建湖县| 利辛县| 神农架林区| 醴陵市| 砚山县| 永昌县| 乌兰县| 甘谷县| 海丰县| 正镶白旗| 澜沧| 专栏| 鹤山市| 德化县| 宁河县| 屏山县| 京山县| 澜沧| 宁德市| 正宁县| 万年县| 张掖市| 壶关县| 荆州市| 洛阳市| 鄂托克旗| 临颍县| 临湘市| 邵东县| 竹山县| 怀集县| 郧西县| 邹城市| 同德县| 昌黎县| 赤峰市| 临泽县| 吴旗县| 察雅县| 祁东县| 准格尔旗|