

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、2024/3/17,第十三章 編譯預處理和動態(tài)存儲分配,甘肅聯合大學 電信學院 曹曉麗,2024/3/17,第一節(jié) 編譯預處理,編譯預處理:C編譯程序對C源程序進行編譯之前,由編譯預處理程序對編譯預處理命令進行處理的過程 C語言中,凡是以“#”開頭的行,都稱為“編譯預處理”命令行,每行的末尾不得用“;”號結束,以區(qū)別于C語言中的語句、定義和說明語句。它們可以出現在程序的任何一行的開始位置,作用域是從出現點到本文件末尾。,2
2、024/3/17,第一節(jié) 編譯預處理,C語言的預處理命令有: #define、#undef、#include、#if、#else、#elif、#endif、#ifdef、#ifndef、#line、#pragma、#error。本章將重點介紹#define和#include命令行的應用,2024/3/17,第一節(jié) 編譯預處理,一、宏替換宏替換是用#define指定的預處理1.不帶參數的宏定義1> 不帶參數的宏定義命
3、令行形式#define 宏名 替換文本 或#define 宏名,2024/3/17,第一節(jié) 編譯預處理,如: #define size 100 以上標識符size是宏名,是用戶定義的標識符,不得與程序中的其它名字相同。在編譯時,在此命令之后,預處理程序對源程序中的所有名為size的標識符用100三個字符來替換,這個替換過程稱為“宏替換”。這是一種簡單的字符替換,不進行任何計算。所以不要認為“size等于
4、整數100”。,2024/3/17,第一節(jié) 編譯預處理,例:#define PI 3.1415926#define R 3.0double circle(){ return 2.0*PI*R;}double area(){ return PI*R*R;},2024/3/17,第一節(jié) 編譯預處理,經過預處理后將形成以下源文件:double circle(){ return 2.0*3.1415926*3.0;
5、}double area(){ return 3.1415926*3.0*3.0;},2024/3/17,第一節(jié) 編譯預處理,使用宏替換的好處是:提高程序可讀性易修改性好,若用宏替換將半徑R修改為5,則只需修改1處,否則需修改3處 #define命令行可以不包含“替換文本”,這種情況下僅說明標識符“被定義”。,2024/3/17,第一節(jié) 編譯預處理,2> 替換文本中可以包含已定義過的宏名例如:#defi
6、ne PI 3.14 #define ADDPI (PI+1) #define TWO-ADDPI (2*ADDPI) 程序中若有表達式:x=TWO-ADDPI/2,則表達式將成為x=(2*(3.14+1))/2。 若第二、三行的替換文本不加括號,直接寫成PI+1和2*ADDPI,則以上表達式被替換為x=2*3.14+1/2,所以,使用宏替換時一般要求把替換文
7、本用()括起來,2024/3/17,第一節(jié) 編譯預處理,3> 若宏定義在一行中寫不下時,在行尾加“\”表示要續(xù)行,若“\”前或下一行的開頭有空格,則在宏替換時也加入空格如:#define LEAP-YEAR year%4\&& year&100!=0||year%400==0第一列4> 同一宏名不能重復定義,除非兩個宏定義命令行完全一致,但這沒有意義,2024/3/17,第一節(jié) 編
8、譯預處理,5> 替換文本不能替換雙引號中與宏名相同的字符串。如:#define YES 1則不能用1來替換printf(“YES”);當中的YES6> 替換文本不能替換用戶標識符中的成分 如:#define YES 1 int YESORNO; 此處YES不替換7> 宏名通常用大寫字母,但非規(guī)定8> 宏定義一般寫在程序開頭9> 宏名不能用雙引號引起來 #de
9、fine “YES” 1 將不進行宏替換,2024/3/17,第一節(jié) 編譯預處理,2. 帶參數的宏定義1> 帶參數的宏定義命令行形式#define 宏名(形參表) 替換文本 如; #define MU(x,y) ((x)*(y)) 宏名 宏 a=MU(5,2) a=((5)*(2)) b=6/MU(a+3,a) b=6/((
10、a+3)*(a)) 宏名和(必須緊挨著,不得留空格;各形參之間用逗號隔開;“替換文本”中通常應該包含形參。,,,2024/3/17,第一節(jié) 編譯預處理,2> 同一宏名不能重復定義,除非兩個宏定義命令行完全一致 在預編譯時,編譯預處理程序用“替換文本”來替換宏,并用對應的實參來替換“替換文本”中的形參3> 替換帶參數的宏名時,一對圓括號必不可少。圓括號中的實參應與形參個數相同,若有多個參數,他們之間用逗號隔
11、開。,2024/3/17,第一節(jié) 編譯預處理,4> 替換文本中的形參和整個表達式應該用括號括起來#define MU(x,y) (x)*(y)b=6/MU(a+3,a) b=6/(a+3)*(a)#define MU(x,y) x*yb=6/MU(a+3,a) b=6/a+3*a,2024/3/17,第一節(jié) 編譯預處理,5> 宏替換和函數調用有相似之處,但宏替換對參數無類型要求,
12、整型也可,實型也可;函數調用中,對不同類型的參數,需定義不同的函數。6> 宏替換是在編譯時由預處理程序完成的,不占運行時間,但需占用大量空間;函數調用是程序運行時進行的,需占運行時間,但不需占用大量空間。7> 宏替換中,實參不能替換雙引號中的形參例 : #define LET(x,v) x=v #define PRT(f,i) printf(f,i),2024/3/17,第一節(jié) 編譯預處理,P1
13、82 EX13.1#define MIN(x,y) (x)<(y)?(x):(y)main(){ int i,j,k; i=10; j=15; k=10*(i)<(j)?(i):(j); printf(“%d\n”,k);} 結果:15,2024/3/17,第一節(jié) 編譯預處理,3. 終止宏定義 1> 形式:#undef 宏名 2> 提前終止宏定義的作用域 如:#
14、define PI 3.1415 main() … #undef PI …PI 無效,定義域已結束無定義,2024/3/17,第一節(jié) 編譯預處理,二.文件包含 在用C語言開發(fā)程序時,我們把一些宏定義按照功能分別放入不同的文件中。當我們需要使用某類宏定義時,就無須在程序中重新定義,而只要把這些宏定義所在的文件包含在程序的開頭就可以了(當然文件中還可以包含其他內容)
15、 所謂文件包含是指在一個文件中,去包含另一個文件的全部內容。C語言中用#include命令行來實現文件包含的功能。,2024/3/17,第一節(jié) 編譯預處理,#include命令行的形式如下: #include “文件名” 首先在源文件所在的目錄內查找指定的包含文件,如果找不到,再按照系統(tǒng)指定的標準方式到有關目錄去尋找或 #include 系統(tǒng)將直接按照系統(tǒng)指定的標準方式到有關目錄去尋找。 在預編
16、譯時,預編譯程序將用指定文件中的內容來替換命令行。,2024/3/17,第一節(jié) 編譯預處理,說明:1> #include命令行通常書寫在文件開頭,故有時把包含文件稱為頭文件,頭文件名可以由用戶指定,擴展名不一定用“h”,但這是指自定義的頭文件2> (被)包含文件中,一般包含一些公用的#define命令行、外部說明(如:extern)或對(庫)函數的原型說明。如:stdio.h3>(被)包含文件修改后,對包含該文件
17、的源程序必須重新編譯連接,2024/3/17,第一節(jié) 編譯預處理,4> 在一個程序中,允許有任意多個#include命令行5> (被)包含文件中還可以包含其它文件,2024/3/17,第二節(jié) 動態(tài)存儲分配,我們在前面講述表示符的存儲類型時曾講過,計算機的內存可分為四個區(qū):程序代碼區(qū)、靜態(tài)數據區(qū)、棧區(qū)、堆區(qū)。程序代碼區(qū)用于存放C語言中各函數的程序代碼;靜態(tài)存儲區(qū)用來存放全局變量及靜態(tài)局部變量(靜態(tài)類);棧區(qū)用來存放自動類別的
18、局部變量(自動類)和函數調用時的返回地址。無論是靜態(tài)變量還是自動變量,在變量的生存期內它們所占的存儲空間都是固定不變的,所以這種分配方式為靜態(tài)存儲分配。,2024/3/17,第二節(jié) 動態(tài)存儲分配,C語言中還有一種稱為“動態(tài)存儲分配”的內存分配方式。 即在程序執(zhí)行期間需要存儲空間來存儲數據時,通過“申請”分配指定的內存空間。當有空閑不用的空間時,可以隨時將其釋放,由系統(tǒng)另作它用。而這些被動態(tài)分配的空間正是內存的堆區(qū),這個區(qū)域由C語言提供的
19、標準庫函數進行管理,從而得到指定數目的內存空間或釋放指定的內存空間。,2024/3/17,第二節(jié) 動態(tài)存儲分配,ANSI C為動態(tài)分配,系統(tǒng)提供了四個庫函數:malloc、calloc、free和realloc,需用包含頭文件stdlib.h 一.malloc函數和free函數1. malloc函數 它的作用是在內存開辟指定大小的存儲空間,并將此存儲空間的首地址作為函數值返回,函數的原型是: void *malloc(un
20、signed int size),2024/3/17,第二節(jié) 動態(tài)存儲分配,含義: 分配size個字節(jié)的存儲區(qū),返回一個指向存儲區(qū)首地址的基類型為void的地址值(存儲區(qū)首地址)。不規(guī)定指向任何具體類型的數據,若想將這個地址值賦給其它類型的指針變量,需用強制類型轉換的方法把void指針轉換成所需類型;若沒有足夠的內存單元供分配,函數返回空(NULL),2024/3/17,第二節(jié) 動態(tài)存儲分配,如: short *pi
21、; pi=(short *)malloc(sizeof(short)); if(pi!=NULL) *pi=6; 由動態(tài)分配得到的存儲單元沒有名字,只靠指針變量來引用。一旦指針指向改變,原存儲單元及其所存數據都將無法引用。通過malloc分配的存儲單元中沒有確定的初值。,2024/3/17,第二節(jié) 動態(tài)存儲分配,在動態(tài)分配存儲空間時,若不能確定數據類型所占的字節(jié)數,可以使用sizeof運算符來求得。sizeo
22、f(類型名)是一個整型表達式,其值為此類型變量所占的字節(jié)數。 例如: pi=(int *)malloc(sizeof(int)); 這是一種常用的格式,此時由系統(tǒng)指定指定類型所占的字節(jié)數。 那么,如果想分配能存放8個整型變量的空間,該怎么調用呢? pi=(int *)malloc(8*sizeof(int)); 這是一種常用格式。,2024/3/17,第二節(jié) 動態(tài)存儲分配,2. free函數
23、 函數的調用形式:free(p) 這里指針變量p必須指向由函數malloc或calloc分配的地址。free函數將釋放指針p所指的存儲空間,使這部分空間可以由系統(tǒng)重新支配。函數無返回值。,2024/3/17,第二節(jié) 動態(tài)存儲分配,二.calloc函數 其函數原型為:void *calloc(unsigned int n,unsigned int size)如:calloc(n,size) 其函
24、數用來給n個大小為size的同一類型的數據項分配連續(xù)的存儲空間。若分配成功返回首地址,如果需賦值,則要進行強制類型轉化;若分配失敗,返回空,2024/3/17,第二節(jié) 動態(tài)存儲分配,如: char *ps; ps=(char *)calloc(10,sizeof(char)); 主要用于開辟連續(xù)的存儲空間存放數組元素,其中第一個參數決定了一維數組的數組元素個數;第二個參數決定了數組元素的類型。函數的返回值為數組的首地址,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 第2章_數據存儲預處理
- 第六章 函數、存儲類和預處理程序
- 三存儲管理動態(tài)不等長存儲資源分配算法
- 多核處理器的事務存儲模型的模擬和編譯實現.pdf
- c語言程序設計_2 第10章 編譯預處理
- 分配存儲
- SAR實時處理器預處理和轉置存儲技術的研究與實現.pdf
- [學習]樊媛媛c語言程序設計09-編譯預處理
- 基于Hadoop的Web日志存儲及預處理優(yōu)化研究.pdf
- 操作系統(tǒng)課程設計---動態(tài)分區(qū)分配存儲管理
- 基于動態(tài)任務分配策略的主動存儲系統(tǒng).pdf
- 快遞站點貨柜存儲空間動態(tài)分配優(yōu)化研究.pdf
- 動態(tài)分區(qū)主存的分配和回收
- 原料乳的驗收和預處理
- 基于嵌入式系統(tǒng)的在線動態(tài)簽名的數據采集和預處理.pdf
- 分布式存儲系統(tǒng)上數據劃分技術和編譯實現.pdf
- 入水預處理
- 并行數據處理中間件存儲分配策略研究.pdf
- 大數據的存儲和處理研究.pdf
- 靈活預處理GPBiCG和并行BiCG方法.pdf
評論
0/150
提交評論