首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言條件編譯:#ifdef / #ifndef / #if / #else / #endif 完全指南

     編輯:關於C語言

C 語言條件編譯:#ifdef / #ifndef / #if / #else / #endif 完全指南

條件編譯讓源碼部分內容僅在滿足特定條件時參與編譯,提高代碼可移植性與可配置性。

基本形式

#ifdef IDENTIFIER
    // 程序段 1:IDENTIFIER 已定義時編譯
#else
    // 程序段 2:未定義時編譯 (可省略)
#endif

常見變體

  • #ifndef IDENTIFIER:未定義時編譯程序段 1,與 #ifdef 邏輯相反。
  • #if EXPRESSION:表達式非零(真)編譯程序段 1,零(假)編碼段 2。表達式可含定義的宏常量。

核心應用場景

1. 跨平台類型適配

#ifdef WINDOWS
#define MYTYPE long
#else
#define MYTYPE float
#endif

Windows 編譯前定義 #define WINDOWS,其他平台不定義。同一源碼無需修改即可適配多平台。

2. 調試開關

#ifdef DEBUG
    printf("device_open(%p)\n", file);
#endif

調試時定義 #define DEBUG,發布時刪除該行,所有 DEBUG 區塊自動失效,如同總開關,避免手動刪改大量 printf。

3. 表達式條件編譯

#define LETTER 1
// ...
#if LETTER
    if (c >= 'a' && c <= 'z') c = c - 32; // 轉大寫
#else
    if (c >= 'A' && c <= 'Z') c = c + 32; // 轉小寫
#endif

修改 LETTER 為 0/1 即可切換功能,目標代碼更精簡(未編譯分支不生成指令)。

工程實踐妙用(大型項目)

  • 功能模塊裁剪:#ifdef HNLD 包含特定客戶模塊 #include "n166_hn.c"。發布其他客戶版本時僅註釋宏定義。
  • 運行追蹤:每子程序入口加 #ifdef DEBUG printf("Now in ...\n"); #endif。
  • 繞過硬件依賴:本地缺設備時 #ifndef TEST i = dial(); #else i = 0; #endif。調試通過後屏蔽 TEST 發布。

頭文件防重複包含:標準護衛宏

#ifndef _STDIO_H_
#define _STDIO_H_
// ... 頭文件內容 ...
#endif
  • 宏名規則:文件名全大寫,前後加下劃線,點替換為下劃線。如 stdio.h → _STDIO_H_。
  • 無論頭文件是否被多文件引用,**務必添加**,防止重複定義導致編譯/鏈接錯誤。

頭文件中定義變量的陷阱

// 錯誤示範
#ifndef AAA
#define AAA
int i;  // 定義變量
#endif

多 .cpp 包含此頭文件並鏈接時,C++ 報「重複定義」;C 可能通過(弱符號機制)。
解決:頭文件只 extern int i; 聲明,在一個 .c/.cpp 中定義 int i;。

總結

  • #ifdef/#ifndef 檢查宏是否定義;#if 判斷表達式真假。
  • 善用條件編譯實現跨平台、調試開關、功能裁剪、硬件模擬。
  • 頭文件必加護衛宏,勿在頭文件定義變量/函數實體。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved