色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>C語(yǔ)言|源代碼>C語(yǔ)言的編譯預(yù)處理

C語(yǔ)言的編譯預(yù)處理

2009-09-20 | rar | 433 | 次下載 | 5積分

資料介紹

在將一個(gè)C源程序轉(zhuǎn)換為可執(zhí)行程序的過(guò)程中, 編譯預(yù)處理是最初的步驟. 這一步驟是由預(yù)處理器(preprocessor)來(lái)完成的. 在源流程序被編譯器處理之前, 預(yù)處理器首先對(duì)源程序中的"宏(macro)"進(jìn)行處理.
C初學(xué)者可能對(duì)預(yù)處理器沒(méi)什么概念, 這是情有可原的: 一般的C編譯器都將預(yù)處理, 匯編, 編譯, 連接過(guò)程集成到一起了. 編譯預(yù)處理往往在后臺(tái)運(yùn)行. 在有的C編譯器中, 這些過(guò)程統(tǒng)統(tǒng)由一個(gè)單獨(dú)的程序來(lái)完成, 編譯的不同階段實(shí)現(xiàn)這些不同的功能. 可以指定相應(yīng)的命令選項(xiàng)來(lái)執(zhí)行這些功能. 有的C編譯器使用分別的程序來(lái)完成這些步驟. 可單獨(dú)調(diào)用這些程序來(lái)完成. 在gcc中, 進(jìn)行編譯預(yù)處理的程序被稱(chēng)為CPP, 它的可執(zhí)行文件名為cpp.
編譯預(yù)處理命令的語(yǔ)法與C語(yǔ)言的語(yǔ)法是完全獨(dú)立的. 比如: 你可以將一個(gè)宏擴(kuò)展為與C語(yǔ)法格格不入的內(nèi)容, 但該內(nèi)容與后面的語(yǔ)句結(jié)合在一個(gè)若能生成合法的C語(yǔ)句, 也是可以正確編譯的.

(一) 預(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ù)處理命令的名稱(chēng), 它之前以#開(kāi)頭, #之后緊隨預(yù)處理命令, 標(biāo)準(zhǔn)C允許#兩邊可以有空白符, 但比較老的編譯器可能不允許這樣. 若某行中只包含#(以及空白符), 那么在標(biāo)準(zhǔn)C中該行被理解為空白. 整個(gè)預(yù)處理語(yǔ)句之后只能有空白符或者注釋, 不能有其它內(nèi)容.
2, name代表宏名稱(chēng), 它可帶參數(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ù)的宏被稱(chēng)為"對(duì)象宏(objectlike macro)"
#define經(jīng)常用來(lái)定義常量, 此時(shí)的宏名稱(chēng)一般為大寫(xiě)的字符串. 這樣利于修改這些常量.
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)用該宏, 只需在代碼中指定宏名稱(chēng), 該宏將被替代為它被定義的內(nèi)容.
函數(shù)宏
帶參數(shù)的宏也被稱(chēng)為"函數(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ū)別在于宏名稱(chēng)之后不帶括號(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 insert(stmt) stmt
insert ( a="1"; b="2";) 相當(dāng)于在代碼中加入 a="1"; b="2" .
insert ( a="1", b="2";) 就有問(wèn)題了: 預(yù)處理器會(huì)提示出錯(cuò): 函數(shù)宏的參數(shù)個(gè)數(shù)不匹配. 預(yù)處理器把","視為參數(shù)間的分隔符.
insert ((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ù)類(lèi)型是不敏感的, 你不必考慮將何種數(shù)據(jù)類(lèi)型傳遞給宏. 那么, 如何構(gòu)建對(duì)參數(shù)類(lèi)型敏感的宏呢? 參考本章的第九部分, 關(guān)于"##"的介紹.
?
關(guān)于定義宏的另外一些問(wèn)題
(1) 宏可以被多次定義, 前提是這些定義必須是相同的. 這里的"相同"要求先后定義中空白符出現(xiàn)的位置相同, 但具體的空白符類(lèi)型或數(shù)量可不同, 比如原先的空格可替換為多個(gè)其他類(lèi)型的空白符: 可為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í)別。

下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評(píng)論

查看更多

下載排行

本周

  1. 1電子電路原理第七版PDF電子教材免費(fèi)下載
  2. 0.00 MB  |  1490次下載  |  免費(fèi)
  3. 2單片機(jī)典型實(shí)例介紹
  4. 18.19 MB  |  92次下載  |  1 積分
  5. 3S7-200PLC編程實(shí)例詳細(xì)資料
  6. 1.17 MB  |  27次下載  |  1 積分
  7. 4筆記本電腦主板的元件識(shí)別和講解說(shuō)明
  8. 4.28 MB  |  18次下載  |  4 積分
  9. 5開(kāi)關(guān)電源原理及各功能電路詳解
  10. 0.38 MB  |  10次下載  |  免費(fèi)
  11. 6基于AT89C2051/4051單片機(jī)編程器的實(shí)驗(yàn)
  12. 0.11 MB  |  4次下載  |  免費(fèi)
  13. 7藍(lán)牙設(shè)備在嵌入式領(lǐng)域的廣泛應(yīng)用
  14. 0.63 MB  |  3次下載  |  免費(fèi)
  15. 89天練會(huì)電子電路識(shí)圖
  16. 5.91 MB  |  3次下載  |  免費(fèi)

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234313次下載  |  免費(fèi)
  3. 2PADS 9.0 2009最新版 -下載
  4. 0.00 MB  |  66304次下載  |  免費(fèi)
  5. 3protel99下載protel99軟件下載(中文版)
  6. 0.00 MB  |  51209次下載  |  免費(fèi)
  7. 4LabView 8.0 專(zhuān)業(yè)版下載 (3CD完整版)
  8. 0.00 MB  |  51043次下載  |  免費(fèi)
  9. 5555集成電路應(yīng)用800例(新編版)
  10. 0.00 MB  |  33562次下載  |  免費(fèi)
  11. 6接口電路圖大全
  12. 未知  |  30320次下載  |  免費(fèi)
  13. 7Multisim 10下載Multisim 10 中文版
  14. 0.00 MB  |  28588次下載  |  免費(fèi)
  15. 8開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
  16. 未知  |  21539次下載  |  免費(fèi)

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935053次下載  |  免費(fèi)
  3. 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
  4. 78.1 MB  |  537791次下載  |  免費(fèi)
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420026次下載  |  免費(fèi)
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234313次下載  |  免費(fèi)
  9. 5Altium DXP2002下載入口
  10. 未知  |  233045次下載  |  免費(fèi)
  11. 6電路仿真軟件multisim 10.0免費(fèi)下載
  12. 340992  |  191183次下載  |  免費(fèi)
  13. 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
  14. 158M  |  183277次下載  |  免費(fèi)
  15. 8proe5.0野火版下載(中文版免費(fèi)下載)
  16. 未知  |  138039次下載  |  免費(fèi)
主站蜘蛛池模板: 最近中文字幕MV免费看 | 白丝高中生被c爽哭 | 欧美激情精品久久久久久不卡 | 国产日韩高清一区二区三区 | 最好看中文字幕国语 | 精品手机在线1卡二卡3卡四卡 | 亚洲精品高清在线 | 真实的强视频免费网站 | 99精品免费久久久久久久久日本 | 老板揉搓秘书丰满大乳 | 久草在线福利资站免费视频 | 国产精品资源网站在线观看 | 国产成人精品自拍 | 俄罗斯XBXBXB兽交 | 亚洲 欧美 日韩 卡通 另类 | 日日操天天操夜夜操 | eussse手机电影在线观看 | 动漫美女禁区图 | 99久久精品费精品蜜臀AV | 亚洲免费每日在线观看 | 三级黄色片免费观看 | 久久影院中文字幕 | ewp系列虐杀在线视频 | 日日夜夜操操操 | 国产精品高清m3u8在线播放 | 国产成久久免费精品AV片天堂 | 在线播放成人无码日 | 久热这里在线精品 | 97超级碰久久久久香蕉人人 | 小夫妻天天恶战 | 久久热精品18国产 | 与嫂子同居的日子在线观看 | 啊灬啊别停灬用力啊老师 | 伊人综合在线影院 | 国产精品第100页 | 成人免费看片又大又黄 | 国内精品蜜汁乔依琳视频 | 脱jk裙的美女露小内内无遮挡 | 东北疯狂xxxxbbbb中国 | 老师你奶真大下面水真多 | 亚洲中文日韩日本在线视频 |