#define / #undef /#progma 前處理器
阿新 • • 發佈:2018-11-14
預處理,在程式編譯之前先進行處理,
#define reg register #define do_forever for( ; ; )//實現無限迴圈的語句 #define CASE break;case //會在每個case之前放一個break #define malloc //將語句註釋空,可以有效控制程式隨意引用 #undef malloc //取消定義恢復原本狀態
當定義中的stuff 很長,可以分成幾行,除了最後一行之外,其餘每一行都要加入一個反斜槓 \ ,如下面的例子
#define DEBUG_PRINT printf( "File %s line %d:" \ "x = %d, y = %d, z = %d", \ __FILE__,__LINE__, \ x ,y ,z )
預定義的符號
在define的語句之後不能加“;” 系統在編譯的時候會自動加上去
假設你需要這樣的巨集定義
#define SQUARE(x) ((X) * (X))
這樣就可有效的避免很多問題
使用技巧
#define PRINT( FORMAT , VALUE) \ printf( "The value of " #VALUE \
" is " FORMAT "\n" ,VALUE)
PRINT( "%d" ,x+3);
the value of x+3 is 25
## 會把兩邊的符號連成一個符號,前提是產生的符號必須是合法的 #define ADD_TO_SUM( sum_number , value ) \ sum ## sum_number +=25
ADD_TO_SUM(5,25);
結果 sum5 = 25.
巨集常用語頻繁地執行簡單的計算
比如比較大小 #define MAX( a, b ) ((a) > (b) ? (a) : (b) )
#undef 用於移除去一個巨集定義,如果現存的名字需要被重新定義,舊定義必須先用#undef移除
條件編譯 #if DEBUG printf(`````);
#endif DEBUG 為 1,編譯內容,為0則刪除內容語句
#if
#elif
#else
#endif
#elif 只有前面都是假才能被編譯 #else 只有前面都是假才會編譯
#if defined( symbol ) #ifdef symbol
#if !defined( symbol ) #ifndef symbol
每隊語句之間都是等價的,但是#if的功能更強一點,都是說假如定義了symbol 才會怎麼樣
#if X>0 || defined( ABC ) &&defined (BCD)
巢狀指令
#if defined(OS_UNIX) //#ifdef 也可以代替 #ifdef OPTION1 unix_version_of_option1(); #endif #ifdef OPTION2 unix_version_of_option2(); #endif
#elif defined(OS_MSDOS) #ifdef ---- unix_version_of_option2(); #endif #endif
相比把程式所需的所有宣告放入一個巨大標頭檔案,還不如每個標頭檔案包含用於某個特定函式或模組的宣告的做法更好一些
為了避免重複定義統一標頭檔案
#ifndef _HEADERNAME_H #define _HEADERNAME_H 1 //#define _HEADERNAME_H 也行
#error text of error message
#if defined () stuff ``` #elif defined() stuff ''
#elif defined() ````
#else #error No`````````````
#endif
用error 產生錯誤資訊
#line number “string”//通知前處理器下一行輸入的是行號
#progma 用於支援因編譯器而異的特性 在所有的預處理指令中,#Pragma 指令可能是最複雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和C++語言完全相容的情況下,給出主機或作業系統專有的特徵
#define reg register #define do_forever for( ; ; )//實現無限迴圈的語句 #define CASE break;case //會在每個case之前放一個break #define malloc //將語句註釋空,可以有效控制程式隨意引用 #undef malloc //取消定義恢復原本狀態
當定義中的stuff 很長,可以分成幾行,除了最後一行之外,其餘每一行都要加入一個反斜槓 \ ,如下面的例子
#define DEBUG_PRINT printf( "File %s line %d:" \ "x = %d, y = %d, z = %d", \ __FILE__,__LINE__, \ x ,y ,z )
預定義的符號
符號 | 樣例值 | 含義 |
__FILE__ | "name.c" | 進行編譯的原始檔名 //在確認除錯輸出的來源很有用處 |
__LINE__ | 25 | 檔案當前行的行號 //在確認除錯輸出的來源很有用處 |
__DATE__ | "Jan 31 1995 " | 檔案被編譯的日期 |
__TIME__ | "18 : 04:30 " | 檔案被編譯的時間 |
__STDC__ | 1 | 如果遵循ANSIC,其值就是1,否則為定義 |
在define的語句之後不能加“;” 系統在編譯的時候會自動加上去
假設你需要這樣的巨集定義
#define SQUARE(x) ((X) * (X))
這樣就可有效的避免很多問題
使用技巧
#define PRINT( FORMAT , VALUE) \ printf( "The value of " #VALUE
PRINT( "%d" ,x+3);
the value of x+3 is 25
## 會把兩邊的符號連成一個符號,前提是產生的符號必須是合法的 #define ADD_TO_SUM( sum_number , value ) \ sum ## sum_number +=25
ADD_TO_SUM(5,25);
結果 sum5 = 25.
巨集常用語頻繁地執行簡單的計算
比如比較大小 #define MAX( a, b ) ((a) > (b) ? (a) : (b) )
#undef 用於移除去一個巨集定義,如果現存的名字需要被重新定義,舊定義必須先用#undef移除
條件編譯 #if DEBUG printf(`````);
#endif DEBUG 為 1,編譯內容,為0則刪除內容語句
#if
#elif
#else
#endif
#elif 只有前面都是假才能被編譯 #else 只有前面都是假才會編譯
#if defined( symbol ) #ifdef symbol
#if !defined( symbol ) #ifndef symbol
每隊語句之間都是等價的,但是#if的功能更強一點,都是說假如定義了symbol 才會怎麼樣
#if X>0 || defined( ABC ) &&defined (BCD)
巢狀指令
#if defined(OS_UNIX) //#ifdef 也可以代替 #ifdef OPTION1 unix_version_of_option1(); #endif #ifdef OPTION2 unix_version_of_option2(); #endif
#elif defined(OS_MSDOS) #ifdef ---- unix_version_of_option2(); #endif #endif
相比把程式所需的所有宣告放入一個巨大標頭檔案,還不如每個標頭檔案包含用於某個特定函式或模組的宣告的做法更好一些
為了避免重複定義統一標頭檔案
#ifndef _HEADERNAME_H #define _HEADERNAME_H 1 //#define _HEADERNAME_H 也行
#error text of error message
#if defined () stuff ``` #elif defined() stuff ''
#elif defined() ````
#else #error No`````````````
#endif
用error 產生錯誤資訊
#line number “string”//通知前處理器下一行輸入的是行號
#progma 用於支援因編譯器而異的特性 在所有的預處理指令中,#Pragma 指令可能是最複雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和C++語言完全相容的情況下,給出主機或作業系統專有的特徵