C語言預處理命令解(jie)析
時間:2018-09-26 來源:未知
C語(yu)言(yan)的源代(dai)碼中可以(yi)包括各種編(bian)譯指令,這(zhe)些(xie)指令就稱之(zhi)為預(yu)(yu)處理(li)(li)命(ming)令。雖然(ran)它們(men)實際上(shang)不是(shi)c語(yu)言(yan)的一部(bu)分,但卻擴展了c程(cheng)序(xu)設(she)計(ji)的環境,預(yu)(yu)處理(li)(li)程(cheng)序(xu)和注(zhu)釋(shi)簡(jian)化程(cheng)序(xu)開發(fa)過程(cheng),并且提高程(cheng)序(xu)的可讀性。然(ran)而(er)這(zhe)些(xie)命(ming)令是(shi)在編(bian)譯前(qian)由(you)預(yu)(yu)處理(li)(li)程(cheng)序(xu)對源文件(jian)的預(yu)(yu)處理(li)(li)文件(jian)進(jin)行(xing)加工(gong)。
預(yu)處(chu)理是在c語(yu)言編譯(yi)的(de)4個(ge)階(jie)段(duan)(duan)(預(yu)處(chu)理、編譯(yi)、匯編、鏈接)的(de)第一個(ge)階(jie)段(duan)(duan)。
C語(yu)言(yan)的預處(chu)理功能(neng)有一下3種:
1,宏定義
2,文件(jian)包含
3,條件編譯
分(fen)別用宏定義命(ming)(ming)令、文(wen)件(jian)包含命(ming)(ming)令、條件(jian)編譯命(ming)(ming)令實現,為了與(yu)其他的(de)c語句區(qu)別,預(yu)處(chu)理命(ming)(ming)令以符號#開頭。
下(xia)面領著大家逐個(ge)了解學習(xi)這些預處理命令。
一:宏定義:
不(bu)帶參數的宏(hong)定義
一般形式:
#define 標識符(fu) 字符(fu)串
作用(yong):用(yong)一個特定的標識符來代表一個字符串。
如:#define PI 3.1415926
在(zai)編(bian)譯處理時,把程(cheng)序中在(zai)該命令之后的所有(you)PI都用“3.1415926”替換。這個標識符(名字(zi))稱為“宏名”,在(zai)預編(bian)譯時將宏名替換成字(zi)符串的過程(cheng)叫做“宏展(zhan)開”。
注意:
1,宏名一(yi)般習慣(guan)用大寫來表示;
2,用宏名(ming)代替一個字(zi)符串,可以減少在程序書寫(xie)的過多的繁瑣的事件(jian),當(dang)需要某一個常量(liang)時,只需要改變#define命令即可;
3,宏定(ding)義(yi)簡單的說就是置換,不做正確性檢查,假如(ru)寫錯(cuo)了,預處理也會照樣帶(dai)入(ru),只有在編譯已被(bei)宏展開的源程(cheng)序時才報(bao)錯(cuo);
4,宏定義不(bu)是語句,不(bu)需要分號(hao);
5,宏定(ding)(ding)義程序中函數的外部,作用范圍是在定(ding)(ding)義之后(hou)到本源程序結束;
6,可以使用#undef命令終止宏定(ding)義作用域;例如:
#define H 9.9
main()
{
...........; }
#undef H
gg()
{
.............;}
以上(shang)可(ke)以看出:H的(de)作(zuo)用(yong)域(yu)就只有在main起作(zuo)用(yong)。
7,宏(hong)定(ding)義(yi)(yi)時(shi),可以使(shi)用(yong)已(yi)經定(ding)義(yi)(yi)的(de)宏(hong)定(ding)義(yi)(yi),可以層層置換;
8,對(dui)程序中用雙引號括起(qi)來(lai)的字符(fu),即使與宏名相同,也不會進行置換(huan)(printf()函數的格式化(hua)輸出);
9,宏(hong)定義與定義變量含義不(bu)一樣,只做字符替換,不(bu)會(hui)分配空間;
帶參數的宏:
定(ding)義的一般形式:
#define 宏名(參(can)數(shu)列表(biao)) 字符串
例如:

注意:
1,對(dui)帶參(can)(can)數的(de)(de)宏(hong)展(zhan)開(kai),只(zhi)是(shi)將語句中(zhong)的(de)(de)宏(hong)名(ming)后面(mian)的(de)(de)括號內(nei)的(de)(de)實參(can)(can)字(zi)符串代替#define命(ming)令行中(zhong)的(de)(de)參(can)(can)數;
2,宏定義時,宏名與帶參數的括號不得有空格;
帶參數的宏定義與函數的區別:
函數調(diao)用(yong)時,先求出實參(can)表(biao)達式的值,然后帶形參(can);
而使(shi)用帶(dai)參數(shu)的(de)宏只是進行簡單的(de)字符替換(huan);
函數(shu)調用是(shi)在程序運行時處理的,分配臨時的內存單元(yuan);
而宏展開是在(zai)編譯時(shi)進(jin)行的,在(zai)展開時(shi)并分配內存單(dan)元,不(bu)進(jin)行值(zhi)的傳遞(di)處理,也沒有(you)“返回值(zhi)”的概(gai)念(nian);
函數中的(de)實參和形參都(dou)要定(ding)義類(lei)型,二者類(lei)型要求一致,若不(bu)一致,應進行類(lei)型轉換;
而宏(hong)不(bu)存(cun)在類型(xing)問題,宏(hong)名無類型(xing),參數也無類型(xing),展開時帶入指(zhi)定的字符(fu)即可(ke)。宏(hong)定義時,字符(fu)串可(ke)以是任(ren)何類型(xing)的數據;
調用函數可(ke)以(yi)得到一(yi)個(ge)返回(hui)值;
而(er)用宏(hong)可以設法(fa)得(de)到(dao)幾(ji)個結(jie)果;
使用宏次(ci)數多時,展開后源(yuan)程序長(chang);
而(er)函(han)數調(diao)用不會(hui)使源程序變(bian)長;
宏(hong)替換不(bu)占運(yun)行時(shi)間(jian),只占編譯時(shi)間(jian);
而函數調用則占運行時間(分配單(dan)元、值傳遞、返回等(deng)等(deng));
二:文件包含
含義(yi):指(zhi)將其他文(wen)件(jian)的(de)(de)內容全(quan)部包(bao)(bao)括(kuo)進來,即將另外的(de)(de)文(wen)件(jian)內容包(bao)(bao)含到(dao)本文(wen)件(jian)中。
用法:
#include<文件名(ming)>
或#include”文件名”
#include<文(wen)件(jian)名(ming)>與#include“文(wen)件(jian)名(ming)”的差異。
使(shi)用(yong)<>和(he)""的(de)(de)區別:使(shi)用(yong)尖括號時,系統到存放C庫函(han)數的(de)(de)頭文件的(de)(de)目錄(lu)中去(qu)找(zhao)要(yao)包含(han)的(de)(de)文件,這稱為標(biao)準方(fang)式。使(shi)用(yong)引號時,系統優先在用(yong)戶當前(qian)目錄(lu)下查找(zhao)要(yao)包含(han)的(de)(de)文件,若找(zhao)不到,再(zai)按(an)標(biao)準方(fang)式查找(zhao)。
說明:
1,一(yi)個include命令只能指(zhi)定一(yi)個被包(bao)含文件,若要包(bao)含n個文件,要用n個include命令;
2,如果一個(ge)文(wen)件(jian)包含(han)了1.h,而文(wen)件(jian)1.h用到了3.h的內(nei)容(rong),則可(ke)在(zai)文(wen)件(jian)中如下定(ding)義:
#include“1.h”
#include“2.h”
3,文件包(bao)(bao)含(han)可以(yi)嵌套,即(ji)在一(yi)個(ge)被包(bao)(bao)含(han)文件,又可以(yi)包(bao)(bao)含(han)另一(yi)個(ge)文件
三:條件(jian)編(bian)譯
一般情況(kuang)下,源(yuan)程(cheng)序中所有的文件(jian)(jian)都要(yao)參加(jia)編(bian)譯。但有時只(zhi)需(xu)要(yao)程(cheng)序的一部分代碼進行(xing)編(bian)譯,這(zhe)時就(jiu)要(yao)指定編(bian)譯條件(jian)(jian),這(zhe)就(jiu)是條件(jian)(jian)編(bian)譯。
條件編譯有以(yi)下幾(ji)種形式(shi):
用法1:
#ifdef 標(biao)識(shi)符
程序段1
#else
程序段2
#endif
說明(ming):當定義過標識符,則編(bian)譯程序段(duan)1,否(fou)則編(bian)譯程序段(duan)2。#else部(bu)分可以(yi)省略,即(ji):
#ifdef
程序段1
#endif
用法2:
#ifndef 標識(shi)符
程序段1
#else
程序段2
#endif
說(shuo)明(ming):與(yu)上(shang)一種類(lei)似,只(zhi)不過將ifdef換(huan)成(cheng)ifndef。當未(wei)定(ding)義過標識符,則編譯(yi)程序段(duan)1,否則編譯(yi)程序段(duan)2。#else部分可以省略(lve)
用法3:
#if 表達(da)式(shi)
程序段1
#else
程序段2
#endif
說明:當指(zhi)定的表達式是真(非零)的時候,編(bian)譯(yi)程(cheng)(cheng)序段1,否則編(bian)譯(yi)程(cheng)(cheng)序段2。#else部分可以省略(lve)
以下示(shi)例(防止頭文件重(zhong)復(fu)包含):


