#define 指示詞 (C/C++)
#define 會建立巨集,這是標識符或參數化標識碼與令牌字串的關聯。 定義巨集之後,編譯器就可以使用語彙基元字串替代原始程式檔中出現的每個識別項。
語法
#define 識別碼 token-stringopt
#define 識別碼 (標識符opt, ... , identifieropt ) token-stringopt
備註
#define 指示詞會導致編譯程式以令牌字串取代來源檔案中每個出現的標識碼。 只有在標識元形成令牌時,才會取代標識碼。 也就是說, 如果標識碼 出現在批註、字串中,或做為較長標識碼的一部分,則不會取代標識符。 如需詳細資訊,請參閱 令牌。
Token-string 自變數是由一系列標記所組成,例如關鍵詞、常數或完整語句。 一或多個空格符必須分隔 令牌字串 與 標識碼。 這個空白不會視為替代文字的一部分,也不是接在上一個文字語彙基元之後的任何空白。
#define
沒有令牌字串的 會從來源檔案中移除標識碼的出現次數。 標識元會維持定義,而且可以使用和 #ifdef
指示詞進行測試#if defined
。
第二個語法形式會定義類似函式且具有參數的巨集。 這種形式可接受選擇性參數清單,但必須以括號括住。 定義巨集之後,每個後續出現的identifier(identifier opt, ..., identifieropt ) 會取代為 Token-string 自變數的版本,其實際自變數會取代為正式參數。
正式參數名稱會出現在 Token-string 中,以標記實際值取代的位置。 每個參數名稱都可以在令牌字串中出現多次,而且名稱可以依任何順序顯示。 呼叫中引數的數目必須與巨集定義中參數的數目相符。 盡量使用括號可確保正確解譯複雜的實際引數。
清單中的型式參數是以逗號分隔。 清單中的每個名稱都必須是唯一的,而且清單必須以括號括住。 沒有空格可以分隔 標識碼 和左括弧。 使用列串連 — 將反斜杠 (\
) 放在換行符的正前 — 在多個來源行上使用 long 指示詞。 正式參數名稱的範圍延伸至結束 Token-string 的新行。
如果已在第二種語法形式中定義巨集,則後面接著引數清單的後續文字執行個體會表示巨集呼叫。 原始程式檔中標識碼實例後面的實際自變數會與巨集定義中的對應型式參數相符。 Token-string 中的每個正式參數前面未加上字串化 ()、字元化 (#
#@
), 或標記貼上 (##
) 運算子,或不是後面##
接著運算元,都會由對應的實際自變數取代。 實際引數中的所有巨集都會在指示詞取代型式參數之前展開。 (運算子描述於 預處理器運算子。)
下列具有自變數的巨集範例說明 #define 語法的第二種形式:
// Macro to define cursor lines
#define CURSOR(top, bottom) (((top) << 8) | (bottom))
// Macro to get a random integer with a specified range
#define getrandom(min, max) \
((rand()%(int)(((max) + 1)-(min)))+ (min))
具有副作用的引數有時會造成巨集產生未預期的結果。 指定的正式參數可能會在 Token-string 中出現一次以上。 如果以具有副作用的運算式取代該型式參數,則運算式連同其副作用可能會經過多次求值。 (請參閱下方 的範例Token-Pasting Operator (##).
#undef
指示詞會導致識別碼的前置處理器定義遭到忽略。 如需詳細資訊,請參閱 #undef 指示詞 。
如果所定義的巨集名稱發生在 Token-string 中(即使因為另一個巨集擴充的結果),它也不會展開。
具有相同名稱之巨集的第二 個 #define 會產生警告,除非第二個令牌序列與第一個標記序列相同。
Microsoft 特定的
如果新定義與原始定義在語法上相同,Microsoft C/C++ 可讓您重新定義巨集。 換句話說,這兩個定義可以有不同的參數名稱。 此行為與 ANSI C 不同,這需要兩個定義在語彙上相同。
例如,下列兩個巨集除了參數名稱之外完全相同。 ANSI C 不允許進行這類重新定義,但Microsoft C/C++編譯時不會發生錯誤。
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( a1 * a2 )
另一方面,下列兩個巨集不相同,而且將會在 Microsoft C/C++ 中產生警告。
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( b1 * b2 )
END Microsoft 特定的
此範例說明 #define 指示詞:
#define WIDTH 80
#define LENGTH ( WIDTH + 10 )
第一個陳述式會將識別項 WIDTH
定義為整數常數 80,並根據 LENGTH
定義 WIDTH
和整數常數 10。 出現的每個 LENGTH
都會由 (WIDTH + 10
) 取代。 然後出現的每個 WIDTH + 10
都會依序由運算式 (80 + 10
) 取代。 WIDTH + 10
前後的括號很重要,因為括號可用於控制陳述式中的解譯方式,如下所示:
var = LENGTH * 20;
在前置處理階段之後,陳述式會變成:
var = ( 80 + 10 ) * 20;
該陳述式的判斷值為 1800。 若沒有括號,則結果為:
var = 80 + 10 * 20;
評估為 280。
Microsoft 特定的
使用 /D 編譯程式選項定義巨集和常數的效果與在檔案開頭使用 #define 前置處理指示詞相同。 使用 /D 選項最多可以定義 30 個巨集。
END Microsoft 特定的