亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

C語(yǔ)言

C語(yǔ)言中的預(yù)編譯宏定義

時(shí)間:2024-09-07 10:09:00 C語(yǔ)言 我要投稿
  • 相關(guān)推薦

C語(yǔ)言中的預(yù)編譯宏定義

  導(dǎo)語(yǔ):C初學(xué)者可能對(duì)預(yù)處理器沒(méi)什么概念, 這是情有可原,下面是C中的預(yù)編譯宏定義,一起來(lái)學(xué)習(xí)下吧:

  (一) 預(yù)處理命令簡(jiǎn)介

  預(yù)處理命令由#(hash字符)開(kāi)頭, 它獨(dú)占一行, #之前只能是空白符. 以#開(kāi)頭的語(yǔ)句就是預(yù)處理命令, 不以#開(kāi)頭的語(yǔ)句為C中的代碼行. 常用的預(yù)處理命令如下:

  #define 定義一個(gè)預(yù)處理宏

  #undef 取消宏的定義

  #include 包含文件命令

  #include_next 與#include相似, 但它有著特殊的用途

  #if 編譯預(yù)處理中的條件命令, 相當(dāng)于C語(yǔ)法中的if語(yǔ)句

  #ifdef 判斷某個(gè)宏是否被定義, 若已定義, 執(zhí)行隨后的語(yǔ)句

  #ifndef 與#ifdef相反, 判斷某個(gè)宏是否未被定義

  #elif 若#if, #ifdef, #ifndef或前面的#elif條件不滿足, 則執(zhí)行#elif之后的語(yǔ)句, 相當(dāng)于C語(yǔ)法中的else-if

  #else 與#if, #ifdef, #ifndef對(duì)應(yīng), 若這些條件不滿足, 則執(zhí)行#else之后的語(yǔ)句, 相當(dāng)于C語(yǔ)法中的else

  #endif #if, #ifdef, #ifndef這些條件命令的結(jié)束標(biāo)志.

  defined 與#if, #elif配合使用, 判斷某個(gè)宏是否被定義

  #line 標(biāo)志該語(yǔ)句所在的行號(hào)

  # 將宏參數(shù)替代為以參數(shù)值為內(nèi)容的字符竄常量

  ## 將兩個(gè)相鄰的標(biāo)記(token)連接為一個(gè)單獨(dú)的標(biāo)記

  #pragma 說(shuō)明編譯器信息

  #warning 顯示編譯警告信息

  #error 顯示編譯錯(cuò)誤信息

  (二) 預(yù)處理的文法

  預(yù)處理并不分析整個(gè)源代碼文件, 它只是將源代碼分割成一些標(biāo)記(token), 識(shí)別語(yǔ)句中哪些是C語(yǔ)句, 哪些是預(yù)處理語(yǔ)句. 預(yù)處理器能夠識(shí)別C標(biāo)記, 文件名, 空白符, 文件結(jié)尾標(biāo)志.

  預(yù)處理語(yǔ)句格式: #command name(...) token(s)

  1, command預(yù)處理命令的名稱, 它之前以#開(kāi)頭, #之后緊隨預(yù)處理命令, 標(biāo)準(zhǔn)C允許#兩邊可以有空白符, 但比較老的編譯器可能不允許這樣. 若某行中只包含#(以及空白符), 那么在標(biāo)準(zhǔn)C中該行被理解為空白. 整個(gè)預(yù)處理語(yǔ)句之后只能有空白符或者注釋, 不能有其它內(nèi)容.

  2, name代表宏名稱, 它可帶參數(shù). 參數(shù)可以是可變參數(shù)列表(C99).

  3, 語(yǔ)句中可以利用""來(lái)?yè)Q行.

  e.g.

  # define ONE 1 /* ONE == 1 */

  等價(jià)于: #define ONE 1

  #define err(flag, msg) if(flag)

  printf(msg)

  等價(jià)于: #define err(flag, msg) if(flag) printf(msg)

  (三) 預(yù)處理命令詳述

  1, #define

  #define命令定義一個(gè)宏:

  #define MACRO_NAME(args) tokens(opt)

  之后出現(xiàn)的MACRO_NAME將被替代為所定義的標(biāo)記(tokens). 宏可帶參數(shù), 而后面的標(biāo)記也是可選的.

  對(duì)象宏

  不帶參數(shù)的宏被稱為"對(duì)象宏(objectlike macro)"

  #define經(jīng)常用來(lái)定義常量, 此時(shí)的宏名稱一般為大寫的字符串. 這樣利于修改這些常量.

  e.g.

  #define MAX 100

  int a[MAX];

  #ifndef __FILE_H__

  #define __FILE_H__

  #include "file.h"

  #endif

  #define __FILE_H__ 中的宏就不帶任何參數(shù), 也不擴(kuò)展為任何標(biāo)記. 這經(jīng)常用于包含頭文件.

  要調(diào)用該宏, 只需在代碼中指定宏名稱, 該宏將被替代為它被定義的內(nèi)容.

  函數(shù)宏

  帶參數(shù)的宏也被稱為"函數(shù)宏". 利用宏可以提高代碼的運(yùn)行效率: 子程序的調(diào)用需要壓棧出棧, 這一過(guò)程如果過(guò)于頻繁會(huì)耗費(fèi)掉大量的CPU運(yùn)算資源. 所以一些代碼量小但運(yùn)行頻繁的代碼如果采用帶參數(shù)宏來(lái)實(shí)現(xiàn)會(huì)提高代碼的運(yùn)行效率.

  函數(shù)宏的參數(shù)是固定的情況

  函數(shù)宏的定義采用這樣的方式: #define name( args ) tokens

  其中的args和tokens都是可選的. 它和對(duì)象宏定義上的區(qū)別在于宏名稱之后不帶括號(hào).

  注意, name之后的左括號(hào)(必須緊跟name, 之間不能有空格, 否則這就定義了一個(gè)對(duì)象宏, 它將被替換為 以(開(kāi)始的字符串. 但在調(diào)用函數(shù)宏時(shí), name與(之間可以有空格.

  e.g.

  #define mul(x,y) ((x)*(y))

  注意, 函數(shù)宏之后的參數(shù)要用括號(hào)括起來(lái), 看看這個(gè)例子:

  e.g.

  #define mul(x,y) x*y

  "mul(1, 2+2);" 將被擴(kuò)展為: 1*2 + 2

  同樣, 整個(gè)標(biāo)記串也應(yīng)該用括號(hào)引用起來(lái):

  e.g.

  #define mul(x,y) (x)*(y)

  sizeof mul(1,2.0) 將被擴(kuò)展為 sizeof 1 * 2.0

  調(diào)用函數(shù)宏時(shí)候, 傳遞給它的參數(shù)可以是函數(shù)的返回值, 也可以是任何有意義的語(yǔ)句:

  e.g.

  mul (f(a,b), g(c,d));

  e.g.

  #define (stmt) stmt

   ( a=1; b=2;) 相當(dāng)于在代碼中加入 a=1; b=2 .

   ( a=1, b=2;) 就有問(wèn)題了: 預(yù)處理器會(huì)提示出錯(cuò): 函數(shù)宏的參數(shù)個(gè)數(shù)不匹配. 預(yù)處理器把","視為參數(shù)間的分隔符.

   ((a=1, b=2;)) 可解決上述問(wèn)題.

  在定義和調(diào)用函數(shù)宏時(shí)候, 要注意一些問(wèn)題:

  1, 我們經(jīng)常用{}來(lái)引用函數(shù)宏被定義的內(nèi)容, 這就要注意調(diào)用這個(gè)函數(shù)宏時(shí)的";"問(wèn)題.

  example_3.7:

  #define swap(x,y) { unsigned long _temp=x; x=y; y=_tmp}

  如果這樣調(diào)用它: "swap(1,2);" 將被擴(kuò)展為: { unsigned long _temp=1; 1=2; 2=_tmp};

  明顯后面的;是多余的, 我們應(yīng)該這樣調(diào)用: swap(1,2)

  雖然這樣的調(diào)用是正確的, 但它和C語(yǔ)法相悖, 可采用下面的方法來(lái)處理被{}括起來(lái)的內(nèi)容:

  #define swap(x,y)

  do { unsigned long _temp=x; x=y; y=_tmp} while (0)

  swap(1,2); 將被替換為:

  do { unsigned long _temp=1; 1=2; 2=_tmp} while (0);

  在Linux內(nèi)核源代碼中對(duì)這種do-while(0)語(yǔ)句有這廣泛的應(yīng)用.

  2, 有的函數(shù)宏是無(wú)法用do-while(0)來(lái)實(shí)現(xiàn)的, 所以在調(diào)用時(shí)不能帶上";", 最好在調(diào)用后添加注釋說(shuō)明.

  eg_3.8:

  #define incr(v, low, high)

  for ((v) = (low),; (v) <= (high); (v)++)

  只能以這樣的形式被調(diào)用: incr(a, 1, 10) /* increase a form 1 to 10 */

  函數(shù)宏中的參數(shù)包括可變參數(shù)列表的情況

  C99標(biāo)準(zhǔn)中新增了可變參數(shù)列表的內(nèi)容. 不光是函數(shù), 函數(shù)宏中也可以使用可變參數(shù)列表.

  #define name(args, ...) tokens

  #define name(...) tokens

  "..."代表可變參數(shù)列表, 如果它不是僅有的參數(shù), 那么它只能出現(xiàn)在參數(shù)列表的最后. 調(diào)用這樣的函數(shù)宏時(shí), 傳遞給它的參數(shù)個(gè)數(shù)要不少于參數(shù)列表中參數(shù)的個(gè)數(shù)(多余的參數(shù)被丟棄).

  通過(guò)__VA_ARGS__來(lái)替換函數(shù)宏中的可變參數(shù)列表. 注意__VA_ARGS__只能用于函數(shù)宏中參數(shù)中包含有"..."的情況.

  e.g.

  #ifdef DEBUG

  #define my_printf(...) fprintf(stderr, __VA_ARGS__)

  #else

  #define my_printf(...) printf(__VA_ARGS__)

  #endif

  tokens中的__VA_ARGS__被替換為函數(shù)宏定義中的"..."可變參數(shù)列表.

  注意在使用#define時(shí)候的一些常見(jiàn)錯(cuò)誤:

  #define MAX = 100

  #define MAX 100;

  =, ; 的使用要值得注意. 再就是調(diào)用函數(shù)宏是要注意, 不要多給出";".

  注意: 函數(shù)宏對(duì)參數(shù)類型是不敏感的, 你不必考慮將何種數(shù)據(jù)類型傳遞給宏. 那么, 如何構(gòu)建對(duì)參數(shù)類型敏感的宏呢? 參考本章的第九部分, 關(guān)于"##"的介紹.

  關(guān)于定義宏的另外一些問(wèn)題

  (1) 宏可以被多次定義, 前提是這些定義必須是相同的. 這里的"相同"要求先后定義中空白符出現(xiàn)的位置相同, 但具體的空白符類型或數(shù)量可不同, 比如原先的空格可替換為多個(gè)其他類型的空白符: 可為tab, 注釋...

  e.g.

  #define NULL 0

  #define NULL /* null pointer */ 0

  上面的重定義是相同的, 但下面的重定義不同:

  #define fun(x) x+1

  #define fun(x) x + 1 或: #define fun(y) y+1

  如果多次定義時(shí), 再次定義的宏內(nèi)容是不同的, gcc會(huì)給出"NAME redefined"警告信息.

  應(yīng)該避免重新定義函數(shù)宏, 不管是在預(yù)處理命令中還是C語(yǔ)句中, 最好對(duì)某個(gè)對(duì)象只有單一的定義. 在gcc中, 若宏出現(xiàn)了重定義, gcc會(huì)給出警告.

  (2) 在gcc中, 可在命令行中指定對(duì)象宏的定義:

  e.g.

  $ gcc -Wall -DMAX=100 -o tmp tmp.c

  相當(dāng)于在tmp.c中添加" #define MAX 100".

  那么, 如果原先tmp.c中含有MAX宏的定義, 那么再在gcc調(diào)用命令中使用-DMAX, 會(huì)出現(xiàn)什么情況呢?

  ---若-DMAX=1, 則正確編譯.

  ---若-DMAX的值被指定為不為1的值, 那么gcc會(huì)給出MAX宏被重定義的警告, MAX的值仍為1.

  注意: 若在調(diào)用gcc的命令行中不顯示地給出對(duì)象宏的值, 那么gcc賦予該宏默認(rèn)值(1), 如: -DVAL == -DVAL=1

  (3) #define所定義的宏的作用域

  宏在定義之后才生效, 若宏定義被#undef取消, 則#undef之后該宏無(wú)效. 并且字符串中的宏不會(huì)被識(shí)別

  e.g.

  #define ONE 1

  sum = ONE + TWO /* sum = 1 + TWO */

  #define TWO 2

  sum = ONE + TWO /* sum = 1 + 2 */

  #undef ONE

  sum = ONE + TWO /* sum = ONE + 2 */

  char c[] = "TWO" /* c[] = "TWO", NOT "2"! */

  (4) 宏的替換可以是遞歸的, 所以可以嵌套定義宏.

  e.g.

  # define ONE NUMBER_1

  # define NUMBER_1 1

  int a = ONE /* a = 1 */

  2, #undef

  #undef用來(lái)取消宏定義, 它與#define對(duì)立:

  #undef name

  如夠被取消的宏實(shí)際上沒(méi)有被#define所定義, 針對(duì)它的#undef并不會(huì)產(chǎn)生錯(cuò)誤.

  當(dāng)一個(gè)宏定義被取消后, 可以再度定義它.

  3, #if, #elif, #else, #endif

  #if, #elif, #else, #endif用于條件編譯:

  #if 常量表達(dá)式1

  語(yǔ)句...

  #elif 常量表達(dá)式2

  語(yǔ)句...

  #elif 常量表達(dá)式3

  語(yǔ)句...

  ...

  #else

  語(yǔ)句...

  #endif

  #if和#else分別相當(dāng)于C語(yǔ)句中的if, else. 它們根據(jù)常量表達(dá)式的值來(lái)判別是否執(zhí)行后面的語(yǔ)句. #elif相當(dāng)于C中的else-if. 使用這些條件編譯命令可以方便地實(shí)現(xiàn)對(duì)源代碼內(nèi)容的控制.

  else之后不帶常量表達(dá)式, 但若包含了常量表達(dá)式, gcc只是給出警告信息.

  使用它們可以提升代碼的可移植性---針對(duì)不同的平臺(tái)使用執(zhí)行不同的語(yǔ)句. 也經(jīng)常用于大段代碼注釋.

  e.g.

  #if 0

  {

  一大段代碼;

  }

  #endif

  常量表達(dá)式可以是包含宏, 算術(shù)運(yùn)算, 邏輯運(yùn)算等等的合法C常量表達(dá)式, 如果常量表達(dá)式為一個(gè)未定義的宏, 那么它的值被視為0.

  #if MACRO_NON_DEFINED == #if 0

  在判斷某個(gè)宏是否被定義時(shí), 應(yīng)當(dāng)避免使用#if, 因?yàn)樵摵甑闹悼赡芫褪潜欢x為0. 而應(yīng)當(dāng)使用下面介紹的#ifdef或#ifndef.

  注意: #if, #elif, #else之后的宏只能是對(duì)象宏. 如果name為名的宏未定義, 或者該宏是函數(shù)宏. 那么在gcc中使用"-Wundef"選項(xiàng)會(huì)顯示宏未定義的警告信息.

  4, #ifdef, #ifndef, defined.

  #ifdef, #ifndef, defined用來(lái)測(cè)試某個(gè)宏是否被定義

  #ifdef name 或 #ifndef name

  它們經(jīng)常用于避免頭文件的重復(fù)引用:

  #ifndef __FILE_H__

  #define __FILE_H__

  #include "file.h"

  #endif

  defined(name): 若宏被定義,則返回1, 否則返回0.

  它與#if, #elif, #else結(jié)合使用來(lái)判斷宏是否被定義, 乍一看好像它顯得多余, 因?yàn)橐呀?jīng)有了#ifdef和#ifndef. defined用于在一條判斷語(yǔ)句中聲明多個(gè)判別條件:

  #if defined(VAX) && defined(UNIX) && !defined(DEBUG)

  和#if, #elif, #else不同, #indef, #ifndef, defined測(cè)試的宏可以是對(duì)象宏, 也可以是函數(shù)宏. 在gcc中使用"-Wundef"選項(xiàng)不會(huì)顯示宏未定義的警告信息.

  5, #include , #include_next

  #include用于文件包含. 在#include 命令所在的行不能含有除注釋和空白符之外的其他任何內(nèi)容.

  #include "headfile"

  #include

  #include 預(yù)處理標(biāo)記

  前面兩種形式大家都很熟悉, "#include 預(yù)處理標(biāo)記"中, 預(yù)處理標(biāo)記會(huì)被預(yù)處理器進(jìn)行替換, 替換的結(jié)果必須符合前兩種形式中的某一種.

  實(shí)際上, 真正被添加的頭文件并不一定就是#include中所指定的文件. #include"headfile"包含的頭文件當(dāng)然是同一個(gè)文件, 但#include 包包含的"系統(tǒng)頭文件"可能是另外的文件. 但這不值得被注意. 感興趣的話可以查看宏擴(kuò)展后到底引入了哪些系統(tǒng)頭文件.

  關(guān)于#include "headfile"和#include 的區(qū)別以及如何在gcc中包含頭文件的詳細(xì)信息, 參考本blog的GCC筆記.

  相對(duì)于#include, 我們對(duì)#include_next不太熟悉. #include_next僅用于特殊的場(chǎng)合. 它被用于頭文件中(#include既可用于頭文件中, 又可用于.c文件中)來(lái)包含其他的頭文件. 而且包含頭文件的路徑比較特殊: 從當(dāng)前頭文件所在目錄之后的目錄來(lái)搜索頭文件.

  比如: 頭文件的搜索路徑一次為A,B,C,D,E. #include_next所在的當(dāng)前頭文件位于B目錄, 那么#include_next使得預(yù)處理器從C,D,E目錄來(lái)搜索#include_next所指定的頭文件.

  可參考cpp手冊(cè)進(jìn)一步了解#include_next

  6, 預(yù)定義宏

  標(biāo)準(zhǔn)C中定義了一些對(duì)象宏, 這些宏的名稱以"__"開(kāi)頭和結(jié)尾, 并且都是大寫字符. 這些預(yù)定義宏可以被#undef, 也可以被重定義.

  下面列出一些標(biāo)準(zhǔn)C中常見(jiàn)的預(yù)定義對(duì)象宏(其中也包含gcc自己定義的一些預(yù)定義宏:

  __LINE__ 當(dāng)前語(yǔ)句所在的行號(hào), 以10進(jìn)制整數(shù)標(biāo)注.

  __FILE__ 當(dāng)前源文件的文件名, 以字符串常量標(biāo)注.

  __DATE__ 程序被編譯的日期, 以"Mmm dd yyyy"格式的字符串標(biāo)注.

  __TIME__ 程序被編譯的時(shí)間, 以"hh:mm:ss"格式的字符串標(biāo)注, 該時(shí)間由asctime返回.

  __STDC__ 如果當(dāng)前編譯器符合ISO標(biāo)準(zhǔn), 那么該宏的值為1

  __STDC_VERSION__ 如果當(dāng)前編譯器符合C89, 那么它被定義為199409L, 如果符合C99, 那么被定義為199901L.

  我用gcc, 如果不指定-std=c99, 其他情況都給出__STDC_VERSION__未定義的錯(cuò)誤信息, 咋回事呢?

  __STDC_HOSTED__ 如果當(dāng)前系統(tǒng)是"本地系統(tǒng)(hosted)", 那么它被定義為1. 本地系統(tǒng)表示當(dāng)前系統(tǒng)擁有完整的標(biāo)準(zhǔn)C庫(kù).

  gcc定義的預(yù)定義宏:

  __OPTMIZE__ 如果編譯過(guò)程中使用了優(yōu)化, 那么該宏被定義為1.

  __OPTMIZE_SIZE__ 同上, 但僅在優(yōu)化是針對(duì)代碼大小而非速度時(shí)才被定義為1.

  __VERSION__ 顯示所用gcc的版本號(hào).

  可參考"GCC the complete reference".

  要想看到gcc所定義的所有預(yù)定義宏, 可以運(yùn)行: $ cpp -dM /dev/null

  7, #line

  #line用來(lái)修改__LINE__和__FILE__.

  e.g.

  printf("line: %d, file: %s ", __LINE__, __FILE__);

  #line 100 "haha"

  printf("line: %d, file: %s ", __LINE__, __FILE__);

  printf("line: %d, file: %s ", __LINE__, __FILE__);

  顯示:

  line: 34, file: 1.c

  line: 100, file: haha

  line: 101, file: haha

  8, #pragma, _Pragma

  #pragma用編譯器用來(lái)添加新的預(yù)處理功能或者顯示一些編譯信息. #pragma的格式是各編譯器特定的, gcc的如下:

  #pragma GCC name token(s)

  #pragma之后有兩個(gè)部分: GCC和特定的pragma name. 下面分別介紹gcc中常用的.

  (1) #pragma GCC dependency

  dependency測(cè)試當(dāng)前文件(既該語(yǔ)句所在的程序代碼)與指定文件(既#pragma語(yǔ)句最后列出的文件)的時(shí)間戳. 如果指定文件比當(dāng)前文件新, 則給出警告信息.

  e.g.

  在demo.c中給出這樣一句:

  #pragma GCC dependency "temp-file"

  然后在demo.c所在的目錄新建一個(gè)更新的文件: $ touch temp-file, 編譯: $ gcc demo.c 會(huì)給出這樣的警告信息: warning: current file is older than temp-file

  如果當(dāng)前文件比指定的文件新, 則不給出任何警告信息.

  還可以在在#pragma中給添加自定義的警告信息.

  e.g.

  #pragma GCC dependency "temp-file" "demo.c needs to be updated!"

  1.c:27:38: warning: extra tokens at end of #pragma directive

  1.c:27:38: warning: current file is older than temp-file

  注意: 后面新增的警告信息要用""引用起來(lái), 否則gcc將給出警告信息.

  (2) #pragma GCC poison token(s)

  若源代碼中出現(xiàn)了#pragma中給出的token(s), 則編譯時(shí)顯示警告信息. 它一般用于在調(diào)用你不想使用的函數(shù)時(shí)候給出出錯(cuò)信息.

  e.g.

  #pragma GCC poison scanf

  scanf("%d", &a);

  warning: extra tokens at end of #pragma directive

  error: attempt to use poisoned "scanf"

  注意, 如果調(diào)用了poison中給出的標(biāo)記, 那么編譯器會(huì)給出的是出錯(cuò)信息. 關(guān)于第一條警告, 我還不知道怎么避免, 用""將token(s)引用起來(lái)也不行.

  (3) #pragma GCC system_header

  從#pragma GCC system_header直到文件結(jié)束之間的代碼會(huì)被編譯器視為系統(tǒng)頭文件之中的代碼. 系統(tǒng)頭文件中的代碼往往不能完全遵循C標(biāo)準(zhǔn), 所以頭文件之中的警告信息往往不顯示. (除非用 #warning顯式指明).

  (這條#pragma語(yǔ)句還沒(méi)發(fā)現(xiàn)用什么大的用處)

  由于#pragma不能用于宏擴(kuò)展, 所以gcc還提供了_Pragma:

  e.g.

  #define PRAGMA_DEP #pragma GCC dependency "temp-file"

  由于預(yù)處理之進(jìn)行一次宏擴(kuò)展, 采用上面的方法會(huì)在編譯時(shí)引發(fā)錯(cuò)誤, 要將#pragma語(yǔ)句定義成一個(gè)宏擴(kuò)展, 應(yīng)該使用下面的_Pragma語(yǔ)句:

  #define PRAGMA_DEP _Pragma("GCC dependency "temp-file"")

  注意, ()中包含的""引用之前引該加上轉(zhuǎn)義字符.

  9, #, ##

  #和##用于對(duì)字符串的預(yù)處理操作, 所以他們也經(jīng)常用于printf, puts之類的字符串顯示函數(shù)中.

  #用于在宏擴(kuò)展之后將tokens轉(zhuǎn)換為以tokens為內(nèi)容的字符串常量.

  e.g.

  #define TEST(a,b) printf( #a "<" #b "=%d ", (a)<(b));

  注意: #只針對(duì)緊隨其后的token有效!

  ##用于將它前后的兩個(gè)token組合在一起轉(zhuǎn)換成以這兩個(gè)token為內(nèi)容的字符串常量. 注意##前后必須要有token.

  e.g.

  #define TYPE(type, n) type n

  之后調(diào)用:

  TYPE(int, a) = 1;

  TYPE(long, b) = 1999;

  將被替換為:

  int a = 1;

  long b = 1999;

  (10) #warning, #error

  #warning, #error分別用于在編譯時(shí)顯示警告和錯(cuò)誤信息, 格式如下:

  #warning tokens

  #error tokens

  e.g.

  #warning "some warning"

  注意, #error和#warning后的token要用""引用起來(lái)!

  (在gcc中, 如果給出了warning, 編譯繼續(xù)進(jìn)行, 但若給出了error, 則編譯停止. 若在命令行中指定了 -Werror, 即使只有警告信息, 也不編譯.


【C語(yǔ)言中的預(yù)編譯宏定義】相關(guān)文章:

簡(jiǎn)單講解C語(yǔ)言中宏的定義與使用07-30

C語(yǔ)言宏定義07-01

C 語(yǔ)言中宏的使用08-02

C語(yǔ)言宏定義技巧09-03

C語(yǔ)言的宏定義分析09-10

關(guān)于C語(yǔ)言宏定義的技巧09-21

C語(yǔ)言預(yù)定義宏用法10-06

C語(yǔ)言條件編譯07-22

C語(yǔ)言的編碼編譯08-11

C語(yǔ)言編譯過(guò)程總結(jié)詳解10-31