亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

學習筆記---預處理

2019-11-11 04:42:35
字體:
來源:轉載
供稿:網友

預處理(編譯預處理)

預處理命令:C語言中以符號“#”開頭的命令

示例:#define...   #include...   #ifdef...

含義:

1.在對程序進行編譯之前,根據預處理命令對程序進行相應處理。

2.經過預處理后編譯器才可以對程序進行編譯等處理,得到可供執行的目標代碼。

示意圖:

解析:

如圖,源程序經過編譯和連接生成可執行文件。而預處理命令將在編譯之前被執行。

宏定義

釋義:可以用#define命令將一個指定的標識符(即宏名)來代表一個字符串

分類:

不帶參數:

語法:#define  標識符  字符串

應用法則:原樣替換

典型應用:符號常量

代碼示例:

#include <stdio.h>#include <stdlib.h>/*這個程序用來測試預處理中的不帶參數的宏定義*/#define PI 3.1415926int main(){    float r,l,s;    PRintf("please enter r:");    scanf("%f",&r);    l=2*PI*r;    s=r*r*PI;    printf(" l: %f /n s: %f /n",l,s);    return 0;}結果:

解析:

定義PI3.1415926之后,在編譯前將把代碼段中所有PI都替換成3.1415926,之后再生成目標文件。這種方式能降低出錯的概念,也能提高程序的可讀性。

注意:絕對不要用 #define PI 3.1415926;這樣的形式!因為宏定義的法則是原樣替換,所以會把分號也原樣代入程序!在上述的示例程序中l的計算方程就會變成l=2*3.1415926;*r;一個語句中出現兩個分號,就會帶來致命的差錯!

帶參數:

語法:#define 宏名(參數表)  字符串

例:

#define S(a,b) a*b...area=S(2,4);解析:

此處area=S(2,4)將在編譯前被解析為:area=2*4

代碼示例:

#include <stdio.h>#include <stdlib.h>/*這個程序用來測試預處理中的帶參數的宏定義*/#define S(a,b) a*bint main(){    printf("矩形1面積;%d/n",S(2,4));    printf("矩形2面積:%.2f/n",S(2.3,4.5));    return 0;}結果:

解析:

如上,程序成功計算出了結果。使用帶參數的宏定義同樣能降低出錯的概念。同時大大提升代碼的可讀性。

深度理解:

帶參數宏定義和函數的區別:

1.函數在編譯后會生成目標代碼,且在程序運行到調用行,會跳轉入函數中繼續執行。而帶參數的宏定義將在編譯前被替換成一個常量表達式。在目標代碼中也不會出現任何痕跡。

2.函數的參數、返回值類型都是有嚴格定義的。而宏定義只是進行機械的替換,參數以及其計算的結果的數據類型都需要自行把握。

帶參數宏定義的易錯點:

代碼示例:

#include <stdio.h>#include <stdlib.h>/*這個程序用來測試預處理中的帶參數的宏定義的性質*/#define PI 3.1415926#define S1(r) PI*r*r#define S2(r) PI*(r)*(r)int main(){    float a,b;    a=1;    b=2;    printf("test1:/nr=%.2f,area=%.2f/n",a+b,S1(a+b));    printf("test2:/nr=%.2f,area=%.2f/n",a+b,S2(a+b));    return 0;}結果:

解析:

1.如上,S1S2看似差別不大。但得到的結果卻完全不同。

2.宏定義的法則為原樣替換,所以對于S1(1+2)將被替換為:PI*1+2*1+2??梢钥吹?,因為計算符號優先級的原因,算式完全扭曲了我們希望得到的結果。

3.S2所做的是,給每個參數都帶上一個小括號,這就解決了S1所遇到的問題,并能夠計算出正確的結果。事實上,這也是代碼規范化的一部分。認識的這一點之后,在使用宏定義時,應當盡量給每個參數都加上小括號。以減少錯誤的發生。

文件包含

釋義:一個源文件可以將另外一個源文件的全部內容包含進來。

語法: #include  "文件地址"  或  #include  <文件地址>

圖示:

如圖,在file1.c中加入#include "file2.c"效果相當于將file2.c中所有的代碼拷貝至當前位置。

應用:將源文件與頭文件分離,提高代碼重用性。具體例子在:http://blog.csdn.net/aketoshknight/article/details/54837779大型程序基礎---調用外部頭文件部分

特點——節省程序設計人員的重復勞動:

1.將常用的一組固定常量的定義組成一個文件——方便,易修改。

2.庫函數的開發者將對被調用的函數的原型聲明寫入頭文件,程序員只需要#include<頭文件> ——大大簡化了程序。

3.一行#include ,相當于寫幾十、幾百,甚至更多行內容,提高了效率。

起源——模塊化程序設計的產物:

1.便于多個程序員分別編程。

2.將公用的符號常量或宏定義等可單獨組成一個文件,在其他文件的開頭用包含命令包含該文件即可使用。

3.公用的聲明只寫一次,除節省時間,更可觀的是減少出錯。

include 命令的兩種形式:

1.#include <文件名>

例:#include <stdio.h>

特點:編譯器將在系統目錄(不同的操作系統可能有不同的系統目錄,也可以在編譯器的設置中自行修改系統目錄的地址)中尋找要包含的文件,如果無法找到該文件,則給出出錯信息。

注:對于系統提供的頭文件,既可用尖括號形式,也可用雙撇號形式,但一般用尖括號形式的效率更高。

2.#include "文件名"

例:#include "mymodule.h"

特點:編譯器先按雙引號中指出的文件路徑和文件名查找(如果給出了E:test.c這樣形式的路徑,便會去該處尋找。如果如上所示只給出文件名,將默認在用戶當前目錄(程序所在的目錄)中尋找),若找不到,再去系統目錄中查找。若仍舊無法找到,則給出出錯信息。

注:若要包含的是用戶自己編寫的文件,一般保存在程序目錄中,因此宜用雙撇號形式。

GCC編譯器中的頭文件和庫函數:

頭文件:

如上,MinGW便是一種GCC編譯器,其中的include文件夾里存放著大量系統頭文件可供引用。

庫函數:

如上,在MinGWlib文件夾中,存放著大量的.o目標文件,以及多種.o目標文件打包而成的.a文件(在代碼連編的連接階段,便是使用這里的文件和程序源文件的目標代碼進行連接的)。

注:以上圖示是GCC編譯器的體系,而在VC++VS中,目標文件將打包成.lib.dll文件,而非.a文件。

條件編譯

釋義:根據需要,只編譯程序中的某一部分。

常用形式1:

//define 標識符#ifdef 標識符    程序段1#else    程序段2#endif解析:

ifdef可看成if define的簡寫。當所指定的標識符已經被#define命令定義過,則在程序編譯階段只編譯程序段1,否則編譯程序段2。#endif用來限定#ifdef命令的范圍,其中#else部分可以省略。

常用形式2:

//define 標識符#ifndef 標識符    程序段1#else    程序段2#endif解析:

ifndef可看成if not define的簡寫。和第一種正好相反。

常用形式3:

#if 常量表達式    程序段1#else    程序段2#endif解析:

和常用的if else條件選擇結構的區別在于增加了代表預處理的#。如果常量表達式的值為真(非0),則對程序段1進行編譯,否則對程序段2進行編譯。因此可以使程序在不同條件下完成不同的功能。

代碼示例1:

#include <stdio.h>#include <stdlib.h>/*這個程序用來測試預處理中的條件編譯*///宏定義常量DEBUG#define DEBUGint main(){    int x=1,y=2;    //ifdef 既if define如果宏定義了XX    #ifdef DEBUG        printf("x=%d,y=%d/n",x,y);//當宏定義DEBUG存在,這句代碼將被編譯。而如果宏定義DEBUG不存在,這句代碼將不被編譯。    #endif // DEBUG    printf("x*y=%d/n",x*y);    return 0;}結果1:

代碼示例2:

#include <stdio.h>#include <stdlib.h>/*這個程序用來測試預處理中的條件編譯*///宏定義常量DEBUG//#define DEBUGint main(){    int x=1,y=2;    //ifdef 既if define如果宏定義了XX    #ifdef DEBUG        printf("x=%d,y=%d/n",x,y);//當宏定義DEBUG存在,這句代碼將被編譯。而如果宏定義DEBUG不存在,這句代碼將不被編譯。    #endif // DEBUG    printf("x*y=%d/n",x*y);    return 0;}結果2:

解析:

1.如上示例,通過改變宏定義,運用#ifdef 即可控制代碼中的某一部分是否被編譯。

2.雖然使用if  else條件判斷也能實現類似的效果,但此處的條件判斷是預處理的一種。既這些代碼將在源文件編譯前就被執行,并且在編譯后的.o目標文件中將不會出現這些代碼。

3.這種方式適合在調試程序時使用,當調試完畢時,只需要取消對DEBUG的宏定義,即可一次性消除大量調試用代碼對程序的影響。

代碼示例3:

#include <stdio.h>#include <stdlib.h>/*這個程序用來測試預處理中的條件編譯*/#define R 1int main(){    float c,r,s;    printf("input a number:/n");    scanf("%f",&c);    #if R        r=3.14159*c*c;        printf("area of round is:%f/n",r);    #else        s=c*c;        printf("area of square is:%f/n",s);    #endif // R    return 0;}結果:

解析:

套用if else的使用經驗,可以十分容易的理解。

深入理解:

文件包含的弊端:

假設個文件A.h  B.c  C.c

A.h:

int test=10;....B.c:

include "A.h"int main(){    ....}C.c:

include "A.h"include "B.c"int main(){    ....}當編寫較大的程序時,常會出現此種交叉包含的情況。這樣,在C.c中就會出現A.h被多次包含的問題。既,A.h中的test變量被多次定義。導致編譯出錯。

解決方案:

A.h:

#ifndef MYHEADER#define MYHEADER 1    #define PI 3.14    int NUM=3    .....#endif解析:

1.如上,使用條件編譯之后,完美的解決了這個問題。2.這是一種編碼規范的標準,為了減少代碼的BUG,應當用這種方式定義自己的頭文件。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人小视频在线观看| 久久夜色精品国产欧美乱| 亚洲无线码在线一区观看| 日本在线观看天堂男亚洲| 尤物99国产成人精品视频| 91av在线播放视频| 日韩电影免费在线观看中文字幕| 久久在线免费视频| 久久人人爽人人爽人人片av高清| 欧美日韩国产在线| 日韩激情av在线播放| 欧美在线观看一区二区三区| 日韩精品在线视频观看| 成人综合国产精品| 欧美性猛交xxxx免费看久久久| 成人免费福利在线| 国产精品久久久久不卡| 性欧美视频videos6一9| 国产视频在线观看一区二区| 亚洲精品久久久久久下一站| 亚洲精品国产精品国产自| 91欧美视频网站| 日韩一区av在线| 日本久久亚洲电影| 国产成人精品电影久久久| 中文字幕日韩在线播放| 亚洲免费一在线| 亚洲精品一区av在线播放| 亚洲色图综合网| 欧美另类在线观看| 亚洲视频欧洲视频| 成人网在线免费看| 亚洲人在线观看| 国产欧美日韩中文字幕| 久久99国产精品自在自在app| 欧美大人香蕉在线| 91精品国产综合久久久久久蜜臀| 1769国产精品| 日韩一区在线视频| 中文字幕亚洲一区| 亚洲乱码国产乱码精品精| 国产精品入口日韩视频大尺度| 欧美精品在线极品| 亚洲欧美制服综合另类| 夜夜狂射影院欧美极品| 国产丝袜一区二区三区免费视频| 中文字幕欧美日韩va免费视频| 亚洲欧洲在线免费| 97在线视频国产| 国产+成+人+亚洲欧洲| 国产成人激情小视频| 亚洲成成品网站| 国产这里只有精品| 在线观看国产精品淫| 亚洲免费一在线| 亚洲精品国产综合久久| 国产美女搞久久| 国产啪精品视频| 日韩在线视频免费观看高清中文| 欧美极品少妇xxxxⅹ喷水| 最近日韩中文字幕中文| 欧美激情网友自拍| 欧美成人三级视频网站| 中文字幕日本欧美| 国产日韩在线观看av| 久久精品国产电影| 国产精品 欧美在线| 欧美一区二区三区精品电影| 国产精品人成电影| 九九热在线精品视频| 久久伊人免费视频| 色妞色视频一区二区三区四区| 国产精品高潮呻吟久久av野狼| 少妇高潮 亚洲精品| 啪一啪鲁一鲁2019在线视频| 热草久综合在线| 91精品国产自产在线| 久久综合免费视频| 久久99热精品这里久久精品| 欧美黄色片免费观看| 久久久亚洲天堂| 欧美激情第1页| 国产亚洲一区二区在线| 欧美成人午夜剧场免费观看| 欧美黑人性生活视频| 国产精品久久久久久久久久小说| 亚洲香蕉av在线一区二区三区| 欧美xxxx做受欧美.88| 亚洲图片欧洲图片av| 色悠久久久久综合先锋影音下载| 91高清免费在线观看| 亚洲欧洲黄色网| 亚洲欧洲视频在线| 国产精品尤物福利片在线观看| 日韩免费不卡av| 在线观看亚洲视频| 68精品久久久久久欧美| 亚洲伊人第一页| 日韩精品丝袜在线| 亚洲第一网站免费视频| 亚洲日韩欧美视频一区| 亚洲欧美日韩视频一区| 日韩av三级在线观看| 亚洲欧美日韩一区二区在线| 国产日韩在线观看av| 亚洲欧洲一区二区三区久久| 国产成人精彩在线视频九色| 久久天堂电影网| 国内精品小视频在线观看| 国产激情久久久久| 在线播放精品一区二区三区| 国产精品久久婷婷六月丁香| 欧美亚洲一区在线| 欧美丝袜一区二区三区| 国产日韩精品在线播放| 2021久久精品国产99国产精品| 亚洲精品免费av| 亚洲人成网站999久久久综合| 日韩男女性生活视频| 在线播放国产精品| 国产精品999| 精品动漫一区二区三区| 欧美色道久久88综合亚洲精品| 午夜精品一区二区三区视频免费看| 韩剧1988在线观看免费完整版| 欧美大片网站在线观看| 亚洲国产精品久久久久秋霞不卡| 91成品人片a无限观看| 国内外成人免费激情在线视频| 欧美xxxwww| 国产精品专区一| 久青草国产97香蕉在线视频| 国产女精品视频网站免费| 欧美另类极品videosbest最新版本| 国产精品久久久久久五月尺| 搡老女人一区二区三区视频tv| 亚洲欧洲在线播放| 成人免费观看49www在线观看| 97欧美精品一区二区三区| 亚洲欧洲免费视频| 日韩av影视综合网| 日韩电影中文字幕| 欧美日韩在线一区| 欧美在线免费观看| 国产欧美精品va在线观看| 久久亚洲精品国产亚洲老地址| 亚洲精品国产免费| 精品欧美激情精品一区| 欧美日韩国产限制| 欧美体内谢she精2性欧美| 一本色道久久88亚洲综合88| 亲爱的老师9免费观看全集电视剧| 伊人久久久久久久久久久| 久久综合久久美利坚合众国| 亚洲精美色品网站| 欧美激情视频三区| 成人激情免费在线| 亚洲综合精品伊人久久| 国产乱肥老妇国产一区二| 97视频在线观看视频免费视频| 欧美影院成年免费版| 91在线观看免费高清| 国产午夜精品久久久| 欧美日韩美女在线观看|