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

首頁(yè) > 系統(tǒng) > iOS > 正文

IOS開(kāi)發(fā)之路--C語(yǔ)言預(yù)處理

2020-07-26 03:36:33
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

概述

大家都知道一個(gè)C程序的運(yùn)行包括編譯和鏈接兩個(gè)階段,其實(shí)在編譯之前預(yù)處理器首先要進(jìn)行預(yù)處理操作,將處理完產(chǎn)生的一個(gè)新的源文件進(jìn)行編譯。由于預(yù)處理指令是在編譯之前就進(jìn)行了,因此很多時(shí)候它要比在程序運(yùn)行時(shí)進(jìn)行操作效率高。在C語(yǔ)言中包括三類(lèi)預(yù)處理指令,今天將一一介紹:

宏定義 條件編譯 文件包含

宏定義

對(duì)于程序中經(jīng)常用到的一些常量或者簡(jiǎn)短的函數(shù)我們通常使用宏定義來(lái)處理,這樣做的好處是對(duì)于程序中所有的配置我們可以統(tǒng)一在宏定義中進(jìn)行管理,而且由于宏定義是在程序編譯之前進(jìn)行替換相比定義成全局變量或函數(shù)效率更高。

//// main.c// Pretreatment//// Created by Kenshin Cui on 14-6-28.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include <stdio.h>#define PI 3.14 //宏定義一般大寫(xiě)#define R 10#define S 2*PI*R //在另一個(gè)宏里面引用了上面的宏int main(int argc, const char * argv[]) {  float r=10.5;  double area=PI*r*r;  printf("area=%.2f/n",area);    double a=S;  printf("a=%.2f/n",a);  printf("PI=3.14/n");//注意輸出結(jié)果不是3.14=3.14而是PI=3.14,字符串中的PI并不會(huì)被替換#undef PI //強(qiáng)制終止宏定義,否則它的范圍一直到文件結(jié)束  int PI=3.1415926;  double area2=PI*r*r;  printf("area2=%.2f/n",area2);      return 0;}

宏定義實(shí)際的操作就是在預(yù)處理時(shí)進(jìn)行對(duì)應(yīng)替換,這個(gè)階段不管語(yǔ)法是否正確,而且對(duì)于字符串中出現(xiàn)的宏名不會(huì)進(jìn)行替換。宏定義的功能事實(shí)上是非常強(qiáng)大的,除了簡(jiǎn)單的常量替換還可以傳入?yún)?shù):

//// 1.2.c// Pretreatment//// Created by Kenshin Cui on 14-7-17.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include <stdio.h>#define SUM(a,b) a+b#define SUB(a,b) (a-b)#define MUL (a,b) (a*b) //這么定義是錯(cuò)誤的,預(yù)處理器會(huì)認(rèn)為宏名為”MUL“,替換內(nèi)容為”(a,b) (a*b)“int main(int argc, const char * argv[]) {    int a=2,b=3,c,d;  c=SUM(a, b);  printf("c=%d/n",c); //結(jié)果:c=5  d=SUM(a, b)*2;  printf("d=%d/n"); //結(jié)果:8,為什么不是10呢?因?yàn)樘鎿Q后:d=a+b*2也就是2+3*2=8    int e=SUB(b, a)*2;  printf("(b-a)*2=%d/n",e); //結(jié)果:2,如果SUB定義時(shí)不加括號(hào)這里應(yīng)該是-1    return 0;}

上面我們可以看出帶參數(shù)的宏功能很強(qiáng)大,有點(diǎn)類(lèi)似于函數(shù),同函數(shù)不同的是它只是簡(jiǎn)單的替換,不涉及存儲(chǔ)空間分配,參數(shù)、返回值等問(wèn)題,但是由于它在預(yù)處理階段展開(kāi),所以一般效率較高。使用帶參數(shù)的宏需要注意的就是結(jié)果最好用括號(hào)括起來(lái)否則很容易出現(xiàn)問(wèn)題(在上面的SUM例子中我們應(yīng)該已經(jīng)看到了);還有一點(diǎn)就是帶參數(shù)的宏定義時(shí)名稱(chēng)和參數(shù)之間不要有空格。

條件編譯

條件編譯其實(shí)就是在編譯之前預(yù)處理器根據(jù)預(yù)處理指令判斷對(duì)應(yīng)的條件,如果條件滿足就將對(duì)應(yīng)的代碼編譯進(jìn)去,否則代碼就根本不進(jìn)入編譯環(huán)節(jié)(相當(dāng)于根本就沒(méi)有這段代碼)。

//// main.c// Pretreatment//// Created by Kenshin Cui on 14-06-28.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include <stdio.h>#define COUNT 1int main(int argc, const char * argv[]) {  //判斷是否定義了 COUNT 宏#if defined(COUNT) //等價(jià)于:#ifdef COUNT,相反如果判斷沒(méi)有定義過(guò)則可以通過(guò)#if !defined(COUNT)或者#ifndef COUNT  printf("COUNT defined/n");#endif  //判斷宏定義COUNT是否都與1#if COUNT==1  showMessage("hello,world!/n");#else  say();#endif    return 0;}

文件包含

文件包含指令#include在前面也多次使用過(guò),這里再次強(qiáng)調(diào)一下。首先使用#include“xxx”包含和使用#include <xxx>包含的不同之處就是使用<>包含時(shí),預(yù)處理器會(huì)搜索C函數(shù)庫(kù)頭文件路徑下的文件,而使用“”包含時(shí)首先搜索程序所在目錄,其次搜索系統(tǒng)Path定義目錄,如果還是找不到才會(huì)搜索C函數(shù)庫(kù)頭文件所在目錄。

另外在使用#include的時(shí)候我們需要注意包含文件的時(shí)候是不能遞歸包含的,例如a.h文件包含b.h,而b.h就不能再包含a.h了;還有就是重復(fù)包含雖然是允許的但是這會(huì)降低編譯性能,不妨看一下下面的例子:

上面有三段代碼,在main.c和person.h中都包含了message.h而main.c自身又包含了person.h,這樣程序在預(yù)處理階段會(huì)對(duì)包含內(nèi)容進(jìn)行替換,替換后mian.c中包含了兩個(gè)#include “message.h”雖然沒(méi)有報(bào)錯(cuò),但這會(huì)影響編譯的性能,正確的做法應(yīng)該是這樣的:

其實(shí)就是用宏定義判斷一個(gè)宏是否定義了,如果沒(méi)有定義則會(huì)定義這個(gè)宏,這樣以來(lái)如果已經(jīng)包含過(guò)則這個(gè)宏定義肯定已經(jīng)定義過(guò)了,即使再包含也不會(huì)重新定義了,下面的代碼也就不會(huì)包含進(jìn)去。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 夏邑县| 黄梅县| 康保县| 涿鹿县| 北海市| 南丰县| 浮山县| 兴隆县| 长兴县| 大荔县| 阿鲁科尔沁旗| 门头沟区| 灌云县| 关岭| 秀山| 定兴县| 和林格尔县| 甘谷县| 宁武县| 平谷区| 太白县| 临澧县| 扶余县| 洪洞县| 宜州市| 克什克腾旗| 卓尼县| 甘南县| 龙川县| 乌鲁木齐县| 安顺市| 娄烦县| 双牌县| 黔西县| 上思县| 崇仁县| 上高县| 榆树市| 宁陕县| 洪湖市| 上饶县|