国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C語言中如何去理解預(yù)處理階段

2019-11-09 21:07:23
字體:
供稿:網(wǎng)友

C語言如何去理解預(yù)處理階段

預(yù)處理

宏定義( 無參宏定義,帶參宏定義)

條件編譯

文件包含

預(yù)處理操作符號(hào)和預(yù)定義宏

下面將會(huì)依次的去介紹各個(gè)階段中的一些細(xì)節(jié)性東西

預(yù)處理

首先在C語言編譯的時(shí)候,會(huì)經(jīng)歷以下幾個(gè)步驟:預(yù)處理,編譯,匯編,鏈接,然后生成可執(zhí)行文件。整個(gè)過程是一連串動(dòng)作完成的。而預(yù)處理階段呢,也是在最先執(zhí)行的一個(gè)步驟。相對(duì)來說,也是比較重要的一個(gè)步驟。

概念: 以“#”號(hào)開頭的預(yù)處理指令如包含#include,宏定義制定#define等,在源程序中這些指令都放在函數(shù)之外,而且一般放在源文件的前面 ,所謂預(yù)處理其實(shí)就是在編譯的第一遍掃描之前的所作的工作,預(yù)處理是C語言的一個(gè)重要的功能,它由預(yù)處理程序單獨(dú)完成,當(dāng)對(duì)一個(gè)源文件進(jìn)行編譯時(shí),系統(tǒng)自動(dòng)引用預(yù)處理程序,預(yù)處理在 源代碼編譯之前對(duì)其進(jìn)行的一些文本性質(zhì)的操作,對(duì)源程序編譯之前做一些處理,生成擴(kuò)展的C源程序

預(yù)處理階段做了任務(wù): 1:將頭文件中的內(nèi)容(源文件之外的文件)插入到源文件中 2:進(jìn)行了宏替換的過程,定義和替換了由#define指令定義的符號(hào) 3:刪除掉注釋的過程,注釋是不會(huì)帶入到編譯階段 4:條件編譯

預(yù)處理指令:

gcc -E bin/helloworld.i src/helloworld.c預(yù)處理生成的是.i的文本文件,這個(gè)文本文件是可以直接通過cat命令進(jìn)行文本文件查看的

宏定義

在C語言中允許用一個(gè)標(biāo)識(shí)符來表示一個(gè)字符串;稱為宏,在預(yù)處理時(shí),對(duì)程序的宏進(jìn)行替換,其中宏定義是由源程序中的#define來完成 ,而宏的替換,主要是由預(yù)處理程序完成的

#define PI 3.1415

宏定義的規(guī)則:

#表示一條預(yù)處理的指令,以#開頭的均是預(yù)處理指令#define是宏定義的指令,標(biāo)識(shí)符是所定義的宏名宏名一般都是大寫的字母表示,以便和變量名區(qū)別宏定義其實(shí)并不是C語言的語句,所以后面是不用去加;號(hào)宏體可以是常數(shù),表達(dá)式,格式化字符串等,為表達(dá)式的時(shí)候應(yīng)該用括號(hào)闊起來宏替換不分配內(nèi)存空間,也不做正確性的檢查宏的范圍是從定義后到本源文件的結(jié)束,但是可以通過#undef來進(jìn)行提前取消

宏定義分為有參宏定義和無參宏定義: 無參宏定義:

語法: #define 標(biāo)識(shí)符(宏名)[字符串] 宏體可缺省: #define YES 1 #define NO 0 #define OUT 帶參宏定義:

帶參宏定義的語法結(jié)構(gòu) #define 宏名(形參列表) 字符串(宏體) 帶參數(shù)宏定義調(diào)用: 宏名(實(shí)參表); C語言中允許宏帶有參數(shù),在宏定義的參數(shù)中稱為形式參數(shù),形式參數(shù)不分配內(nèi)存單元,沒有類型定義; #define S(a,b) a*b; area = S(3,2); 宏展開 area = 3 * 2; 注意事項(xiàng): 帶參數(shù)宏定義中,宏名和形式參數(shù)列表之間不能有空格出現(xiàn)。如 #define MAX (a,b) (a>b)?a:b 此時(shí)MAX為無參的宏定義,宏體為(a,b) (a>b)?a:b #define MAX(a,b) (a>b)?a:b 宏定義中,形參是一個(gè)標(biāo)識(shí)符,而宏調(diào)用的參數(shù)可以是一個(gè)表達(dá)式 宏體內(nèi)的形參通常要括號(hào)闊起來 #define POWER(x) ((x)*(x))

從帶參數(shù)的宏定義中我們可以發(fā)現(xiàn),其在很多場(chǎng)合下,是可以看作是一個(gè)函數(shù)來使用的,但是與真正的函數(shù)又是有著很大的區(qū)別的,所以以下是總結(jié)出來的函數(shù)與宏之間的幾點(diǎn)區(qū)別: 區(qū)別: 區(qū)別

對(duì)比項(xiàng) 帶參數(shù)宏定義 函數(shù)
處理時(shí)間 編譯時(shí)期 程序運(yùn)行時(shí)期
參數(shù)類型 無參數(shù)類型 有具體的參數(shù)類型
處理過程 不分配內(nèi)存,簡單字符的置換 分配內(nèi)存,先求得實(shí)參,再傳遞給形參
程序長度 會(huì)變長 不變
運(yùn)行速度 不會(huì)占用運(yùn)行時(shí)間 調(diào)用和返回會(huì)占用時(shí)間
支持遞歸 宏定義是不會(huì)支持遞歸的 函數(shù)支持遞歸

條件編譯

條件編譯的概念 1:一般情況下,源程序中所有的行都進(jìn)行編譯,但是有時(shí)希望對(duì)其中一部分內(nèi)容滿足一定條件下才進(jìn)行編譯,也就是對(duì)一部分內(nèi)容指定編譯條件,這就是條件編譯

條件編譯的優(yōu)點(diǎn) 條件編譯可以指定代碼的一部分是被正常編譯還是被完全忽略 條件編譯有利于提升程序的可移植性,增強(qiáng)程序 的靈活性

條件編譯的相關(guān)語法 條件編譯語法一:

#ifdef 標(biāo)識(shí)符(宏名) //或者#if define(標(biāo)識(shí)符) 程序段1 #else 程序段2 #endif實(shí)例代碼:防止多重包含的問題產(chǎn)生#define HELLO "helloworld"#ifdef HELLO #define HI "welcome"#endif

條件編譯語法二:

#ifndef 標(biāo)識(shí)符(宏名) //或#if !define(標(biāo)識(shí)符) 程序段1 #else 程序段2 #endif 實(shí)例: #ifndef __HELLO_H__ #define __HELLO_H__ void out(); #else //程序段2 #endif

條件編譯語法三:

#if(常量表達(dá)式) 程序段1 #elif(常量表達(dá)式2) 程序段2 #else 程序段3 #endif實(shí)例代碼: #define C1 0 #define C2 0 #define C3 1 #if(C1) #include "c1.h" #elif(C2) #include "c2.h" #elif(C3) #include "c3.h" #else #include "c.h" #endif

文件包含

文件包含的概念 文件包含是C預(yù)處理程序的另一個(gè)重要的功能,被包含的文件名字必須使用雙引號(hào)”“(自定義頭文件),或者<>(標(biāo)準(zhǔn)庫文件)括起來,

文件包含的語法:

#include <文件名>或者#include "文件名"

文件包含的功能: 一個(gè)源文件可以將另外一個(gè)源文件的內(nèi)容包含進(jìn)來,從而把指定的文件和當(dāng)前的源文件連成一個(gè)源文件

文件包含的處理過程: 在預(yù)處理的時(shí)候,用被包含文件的內(nèi)容取代該文件包含指令,再對(duì)包含后的文件作一個(gè)源文件編譯

文件包含的搜索方式

#include<文件名>若指定文件目錄(如include)則會(huì)從指定目錄中去進(jìn)行查找,否則就會(huì)按照標(biāo)準(zhǔn)的方式進(jìn)行查找如:(gcc -o bin/hello -Iinclude src/hello)標(biāo)準(zhǔn)方式:從系統(tǒng)標(biāo)準(zhǔn)文件所在的目錄中去尋找要包含的文件
linux下:/usr/include或者/usr/lib中主要存放的是標(biāo)準(zhǔn)庫文件#include "文件名"先從存放C源文件的目錄中查找,然后從指定的目錄中去查找,最后再從C語言的標(biāo)準(zhǔn)庫文件中去查找

重要:文件的多重包含問題

概念:同一個(gè)文件被包含了多次

結(jié)果:多重包含可能會(huì)出現(xiàn)重復(fù)定義的編譯錯(cuò)誤

解決方式:使用條件編譯(只能是一個(gè)源文件中去解決)來防止多重包含,凡是在頭文件前后,用條件編譯去編譯

如標(biāo)準(zhǔn)頭文件的寫法:#ifndef __HEADER_NAME_H__#define __HEADER_NAME_H__ #include "headername.h"http://其他的代碼#endif

如果在多個(gè)源文件中進(jìn)行多重包含的話,使用多重包含的話是解決不了的。需要檢查。

建議注意: 在頭文件中盡量不要去定義一些全局變量,可以在源文件中去定義,用extern去修飾,將變量的作用于釋放帶整個(gè)程序

預(yù)處理操作符和預(yù)定義宏 預(yù)處理操作符號(hào):#和##

C語言中有兩個(gè)預(yù)處理操作符號(hào)#和##,它可以在#define中使用 操作符號(hào)#通常成為字符串化的操作符號(hào),它把其后的串變成用雙引號(hào)包圍的串 如:#define PRINT(FORMAT,VALUE) printf("the value of" #value "is" FORMAT "/n",VALUE) PRINT("%d",x+3); 連接操作符號(hào)##可以把兩個(gè)獨(dú)立的字符串鏈接成一個(gè)字符串 如: #define ADD_TO_SUM(sum_number,value) sum##sum_number +=value ADD_TO_SUM(5,25);

預(yù)定義宏和其他指令:

__FILE__ 進(jìn)行編譯的源文件名稱__LINE__ 文件當(dāng)前的行號(hào)__DATE__文件被編譯的日期__TIME__文件被編譯的時(shí)間__fun__當(dāng)前所在的函數(shù)名稱其他預(yù)處理#error 自定義輸出的錯(cuò)誤,是不能鏈接生成可執(zhí)行文件的#line 設(shè)置當(dāng)前的文件從哪一行開始計(jì)算 #line 100 "hello.c"#pragma 字節(jié)對(duì)齊預(yù)處理指令 #pragma message("helloworld");----->輸出提示相關(guān)信息

以上是個(gè)人在學(xué)習(xí)過程中所做的一些總結(jié)性東西,如有不對(duì)的地方,希望可以及時(shí)指出,歡迎繼續(xù)訪問。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 湾仔区| 葫芦岛市| 卢湾区| 邯郸市| 万宁市| 琼海市| 阿克陶县| 景德镇市| 旺苍县| 金塔县| 图木舒克市| 金塔县| 新密市| 宁津县| 凤台县| 霍山县| 营口市| 英吉沙县| 孝感市| 肇东市| 西乌| 兰州市| 尉氏县| 宜城市| 佛坪县| 都安| 鄂伦春自治旗| 宿迁市| 上蔡县| 莱阳市| 洪泽县| 厦门市| 隆化县| 民丰县| SHOW| 杭州市| 锦州市| 江山市| 巍山| 孟村| 恭城|