溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言條件編譯怎么用

發(fā)布時間:2022-04-19 13:35:26 來源:億速云 閱讀:182 作者:iii 欄目:開發(fā)技術

本文小編為大家詳細介紹“C語言條件編譯怎么用”,內容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“C語言條件編譯怎么用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

一、基本概念

  • 條件編譯的行為類似于 C 語言中的 if...else...

  • 編譯是預編譯指示命令,用于控制是否編譯某段代碼

下面看一段簡單的條件編譯的代碼:

#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;
}

下面為輸出結果:

C語言條件編譯怎么用

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

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

可以看到宏定義和條件編譯都沒有了,由相應內容取而代之。

二、條件編譯的本質

預編譯器根據條件編譯指令有選擇的刪除代碼

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

if...else... 語句在運行期進行分支判斷

條件編譯指令在預編譯期進行分支判斷

可以通過命令行定義宏

  • gcc -Dmacro=value file.c

  • gcc -Dmacro file.c

下面看一個通過命令行定義宏的代碼:

#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,輸出結果如下:

C語言條件編譯怎么用

三、#include 的本質

  • #include 的本質是將已經存在的文件內容嵌入到當前文件中

  • #include 的間接包含同樣會產生嵌入文件內容的操作

這就出現(xiàn)一個問題,間接包含同一個頭文件是否會產生編譯錯誤?

C語言條件編譯怎么用

下面就來通過一段代碼深入探究:

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;
}

編譯后編譯器報錯,global 重定義:

C語言條件編譯怎么用

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

# 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 里面的東西復制進 test.c,由于 test.h 里面有一個 include "global.h",就把int global = 10; 復制過來,然后復制

const char* NAME = "test.h";

char* hello_world()

{undefined

return "hello world!\n";

}

在然后由于test.c 里面又定義一個#include "global.h",又把int global = 10; 復制過來,造成了重復定義。

條件編譯可以解決頭文件重復包含的編譯錯誤

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

如果沒有定義 header_file.h,則定義,且執(zhí)行里面的代碼;否則,如果定義了,里面的代碼就不會執(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

這樣編譯就能通過了

C語言條件編譯怎么用

四、條件編譯的意義

條件編譯使得我們可以按不同的條件編譯不同的代碼段,因而可以產生不同的目標代碼

#if...#else...#endif 被預編譯器處理,而 if...else... 語句被編譯器處理,必然被編譯進目標代碼

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

  • 不同的產品線共用一份代碼

  • 區(qū)分編譯產品的調試版和發(fā)布版

下面看一段產品線區(qū)分及調試代碼:

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 是指產品是調試版還是發(fā)布版,調試版為 1,發(fā)布版為 0, 宏 HIGH指的是產品是高端產品還是低端產品,高端產品為 1,低端產品為 0

如果我們想測試調試版的高端產品,令 DEBUG 為 1,HIGH為 0 即可:

C語言條件編譯怎么用

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

C語言條件編譯怎么用

讀到這里,這篇“C語言條件編譯怎么用”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI