![《C語言程序設計》第8章 編譯預處理和動態(tài)存儲分配 寫字字帖_第1頁](http://file4.renrendoc.com/view/ce2baf4ad9adce0565cb5fc897c911fa/ce2baf4ad9adce0565cb5fc897c911fa1.gif)
![《C語言程序設計》第8章 編譯預處理和動態(tài)存儲分配 寫字字帖_第2頁](http://file4.renrendoc.com/view/ce2baf4ad9adce0565cb5fc897c911fa/ce2baf4ad9adce0565cb5fc897c911fa2.gif)
![《C語言程序設計》第8章 編譯預處理和動態(tài)存儲分配 寫字字帖_第3頁](http://file4.renrendoc.com/view/ce2baf4ad9adce0565cb5fc897c911fa/ce2baf4ad9adce0565cb5fc897c911fa3.gif)
![《C語言程序設計》第8章 編譯預處理和動態(tài)存儲分配 寫字字帖_第4頁](http://file4.renrendoc.com/view/ce2baf4ad9adce0565cb5fc897c911fa/ce2baf4ad9adce0565cb5fc897c911fa4.gif)
![《C語言程序設計》第8章 編譯預處理和動態(tài)存儲分配 寫字字帖_第5頁](http://file4.renrendoc.com/view/ce2baf4ad9adce0565cb5fc897c911fa/ce2baf4ad9adce0565cb5fc897c911fa5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
第8章編譯預處理和動態(tài)存儲分配8.1編譯預處理8.2宏定義8.3文件包含處理8.4動態(tài)存儲分配8.1編譯預處理C語言允許在源程序中加入一些“預處理命令”(preprocessingdirective),以改進程序設計環(huán)境,提高編程效率。這些預處理指令是由C標準建議的,但是它不是C語言本身的組成部分,不能用C編譯系統(tǒng)直接對它們進行編譯(因為編譯程序不能識別它們)。所謂“編譯預處理”就是在C編譯程序?qū)源程序進行編譯前,由編譯預處理程序?qū)@些編譯預處理命令行進行處理的過程。在預處理階段,預處理器把程序中的注釋全部刪除;對預處理指令進行處理,如把#include指令指定的頭文件(如stdio.h)的內(nèi)容復制到#include指令處;對#define指令,進行指定的字符替換(如將程序中的符號常量用指定的字符串代替),同時刪去預處理指令。8.1編譯預處理經(jīng)過預處理后的程序不再包括預處理指令了,最后再由編譯程序?qū)︻A處理后的源程序進行實際的編譯處理,得到可供執(zhí)行的目標代碼。C語言與其他高級語言的一個重要區(qū)別是可以使用預處理指令和具有預處理的功能。C語言提供的預處理功能常用的主要有以下3種:1、宏定義;2、文件包含;3、條件編譯。這些預處理命令組成的預處理命令行必須在一行的開頭以”#”號開始,每行的末尾不得用“;”號結(jié)束,以區(qū)別于C語句、定義和說明語句。這些命令行的語法與C語言中其他部分的語法無關。根據(jù)需要,命令行可以出現(xiàn)在程序的任何一行的開始部位,其作用一直持續(xù)到源文件的末尾。8.2宏定義8.2.1不帶參數(shù)的宏定義8.2.2帶參數(shù)的宏定義8.2.3終止宏定義8.2.1不帶參數(shù)的宏定義1不帶參數(shù)的宏定義命令行形式格式:#define宏名替換文本或者:#define宏名在define、宏名和宏替換文本之間用空格隔開。例如:#define SIZE 100以上標識符SIZE稱為“宏名”,是用戶定義的標識符,因此,不得與程序中的其他名字相同。在編譯時,在此命令行之后,預處理程序?qū)υ闯绦蛑械乃忻麨镾IZE的標識符用100三個字符來替換,這個替換過程稱為“宏替換”。但要注意:不能認為“SIZE等于整數(shù)100”。#define命令行可以不包含“替換文本”,這種情況下僅說明標識符“被定義”。8.2.1不帶參數(shù)的宏定義2替換文本中可以包含已定義過的宏名例8.1計算圓面積。#include<stdio.h>#definePI3.1415926#defineR3.0#defineSPI*R*R /*S的宏定義使用了前面的PI和R宏定義*/intmain(){
printf(“圓的面積=%f”,S); return0;}運行結(jié)果:圓的面積=28.274333分析:該例中既有宏定義,又有宏定義的多重替換,這樣求圓的面積,只需將宏名S進行展開后計算,輸出即可。8.2.1不帶參數(shù)的宏定義3當宏定義在一行中寫不下,需要在下一行繼續(xù)時,只需在最后一個字符后緊接著加一個反斜線“\”。例如:#define LEAP_YEAR year%4==0\&&year%100!=0||year%400==0第一列如果在“\”前或在下一行的開頭留有許多空格,則在宏替換時也將加入這些空格。4同一個宏名不能重復定義,除非兩個宏定義命令行完全一致。5替換文本不能替換雙引號中與宏名相同的字符串。例8.2宏名相同的字符串不能替換。#define BOOK “TheRedandTheBlack”intmain(){
printf(“%s\n”,”BOOK”); return0;}運行結(jié)果:BOOK8.2.1不帶參數(shù)的宏定義6替換文本并不替換用戶標識符中的成分。例如,宏名YES,不會替換標識符YESORNO中的YES。7用作宏名的標識符通常用大寫字母表示,這并不是語法規(guī)定,只是一種習慣,以便與程序中的其他標識符相區(qū)別。8在C程序中,宏定義的定義位置一般寫在程序的開頭。返回8.2.2帶參數(shù)的宏定義1帶參數(shù)的宏定義命令行形式如下:格式:#define 宏名(形參表) 替換文本如果定義帶參數(shù)的宏,在對源程序進行預處理時,將程序中出現(xiàn)宏名的地方均用替換文本替換,并用實參代替替換文本中的形參。例8.3編寫程序,使用帶參數(shù)的宏定義。#include<stdio.h>#defineMAX(a,b) a>b?a:b /*定義帶參數(shù)的宏MAX*/#defineSQR(c)c*c /*定義帶參數(shù)的宏SQR*/intmain(){
intx=3,y=4; x=MAX(x,y);
y=SQR(x);
printf(“x=%d,y=%d\n”,x,y);
return0;}運行結(jié)果:x=4,y=16對于帶參的宏定義有以下問題需要說明:2.帶參宏定義中,宏名和形參表之間不能有空格出現(xiàn)。例如把:
#defineMAX(a,b)(a>b)?a:b寫為:
#defineMAX(a,b)(a>b)?a:b將被認為是無參宏定義,宏名MAX代表字符串(a,b)(a>b)?a:b。宏展開時,宏調(diào)用語句:
max=MAX(x,y);將變?yōu)椋?/p>
max=(a,b)(a>b)?a:b(x,y);這顯然是錯誤的。8.2.2帶參數(shù)的宏定義3.在帶參宏定義中,形式參數(shù)不分配內(nèi)存單元,因此不必作類型定義。而宏調(diào)用中的實參有具體的值。要用它們?nèi)ゴ鷵Q形參,因此必須作類型說明。這是與函數(shù)中的情況不同的。在函數(shù)中,形參和實參是兩個不同的量,各有自己的作用域,調(diào)用時要把實參值賦予形參,進行“值傳遞”。而在帶參宏中,只是符號代換,不存在值傳遞的問題。4.在宏定義中的形參是標識符,而宏調(diào)用中的實參可以是表達式。例8.4宏調(diào)用實參為表達式。#defineSQ(y)(y)*(y)main(){
int
a,sq;
printf("inputanumber:");
scanf("%d",&a);sq=SQ(a+1);printf("sq=%d\n",sq);}運行結(jié)果:inputanumber:3sq=16分析:上例中第一行為宏定義,形參為y。程序第七行宏調(diào)用中實參為a+1,是一個表達式,在宏展開時,用a+1代換y,再用(y)*(y)代換SQ,得到如下語句:
sq=(a+1)*(a+1);這與函數(shù)的調(diào)用是不同的,函數(shù)調(diào)用時要把實參表達式的值求出來再賦予形參。而宏代換中對實參表達式不作計算直接地照原樣代換。8.2.2帶參數(shù)的宏定義5.在宏定義中,字符串內(nèi)的形參通常要用括號括起來以避免出錯。在上例中的宏定義中(y)*(y)表達式的y都用括號括起來,因此結(jié)果是正確的。如果去掉括號,把程序改為以下形式:例8.5#defineSQ(y)y*ymain(){
int
a,sq;
printf("inputanumber:");
scanf("%d",&a);sq=SQ(a+1);printf("sq=%d\n",sq);}運行結(jié)果:inputanumber:3sq=7分析:同樣輸入3,但結(jié)果卻是不一樣的。問題在哪里呢?這是由于代換只作符號代換而不作其它處理而造成的。宏代換后將得到以下語句:
sq=a+1*a+1;由于a為3故sq的值為7。這顯然與題意相違,因此參數(shù)兩邊的括號是不能少的。即使在參數(shù)兩邊加括號還是不夠的,請看下面程序:8.2.2帶參數(shù)的宏定義例8.6#defineSQ(y)(y)*(y)main(){
int
a,sq;
printf("inputanumber:");
scanf("%d",&a);sq=160/SQ(a+1);printf("sq=%d\n",sq);}運行結(jié)果:inputanumber:3sq=160分析:本程序與前例相比,只把宏調(diào)用語句改為:
sq=160/SQ(a+1);運行本程序如輸入值仍為3時,希望結(jié)果為10。為什么會得這樣的結(jié)果呢?分析宏調(diào)用語句,在宏代換之后變?yōu)椋?/p>
sq=160/(a+1)*(a+1);a為3時,由于“/”和“*”運算符優(yōu)先級和結(jié)合性相同,則先作160/(3+1)得40,再作40*(3+1)最后得160。為了得到正確答案應在宏定義中的整個字符串外加括號,程序修改如例8.78.2.2帶參數(shù)的宏定義6帶參的宏和帶參函數(shù)很相似,但有本質(zhì)上的不同,除上面已談到的各點外,把同一表達式用函數(shù)處理與用宏處理兩者的結(jié)果有可能是不同的。例8.8main(){
inti=1;
while(i<=5)
printf("%d\n",SQ(i++));}SQ(inty){return((y)*(y));}例8.9#defineSQ(y)((y)*(y))main(){
inti=1;
while(i<=5)
printf("%d\n",SQ(i++));}例8.8運行結(jié)果:1491625例8.9運行結(jié)果:19258.2.2帶參數(shù)的宏定義7宏定義也可用來定義多個語句,在宏調(diào)用時,把這些語句又代換到源程序內(nèi)??聪旅娴睦印@?.10#defineSSSV(s1,s2,s3,v)s1=l*w;s2=l*h;s3=w*h;v=w*l*h;main(){
intl=3,w=4,h=5,sa,sb,sc,vv;
SSSV(sa,sb,sc,vv);
printf("sa=%d\nsb=%d\nsc=%d\nvv=%d\n",sa,sb,sc,vv);}運行結(jié)果:sa=12sb=15sc=20vv=60分析:程序第一行為宏定義,用宏名SSSV表示4個賦值語句,4個形參分別為4個賦值符左部的變量。在宏調(diào)用時,把4個語句展開并用實參代替形參。使計算結(jié)果送入實參之中。返回8.2.3終止宏定義可以用#undef提前終止宏定義的作用域。例如:#definePI3.14main()#undefPI以上PI的作用域從#definePI3.14命令行開始,到#undefPI命令行結(jié)束。從#undef以后PI變成無定義,不再代表3.14了。8.3文件包含處理所謂文件包含,是指在一個文件中,去包含另一個文件的全部內(nèi)容。C語言用#include命令行來實現(xiàn)文件包含的功能。格式:#include “文件名”或 #include <文件名>在預編譯時,預編譯程序?qū)⒂弥付ㄎ募械膬?nèi)容來替換此命令行。如果文件名用雙引號括起來,系統(tǒng)先在源程序所在的目錄內(nèi)查找指定的包含文件,如果找不到,再按照系統(tǒng)指定的標準方式到有關目錄中去尋找;如果文件名用尖括號括起來,系統(tǒng)將直接按照系統(tǒng)指定的標準方式到有關目錄中尋找。說明:1包含文件的#include命令行通常應書寫在所用源程序文件的開頭,故有時也把包含文件稱作“頭文件“。頭文件名可以由用戶指定,其后綴不一定用”.h”。2包含文件中,一般包含有一些公用的#define命令行、外部說明或?qū)Γ◣欤┖瘮?shù)的原型說明。例如stdio.h就是這樣的頭文件。3當包含文件修改后,對包含該文件的源程序必須重新進行編譯連接。4在一個程序中,允許有任意多個#include命令行。5在包含文件中還可以包含其他文件。8.4動態(tài)存儲分配8.4.1malloc函數(shù)和free函數(shù)8.4.2calloc函數(shù)8.4.1malloc函數(shù)和free函數(shù)1malloc函數(shù)格式:(類型說明符*)malloc(size)功能:在內(nèi)存的動態(tài)存儲區(qū)中分配一塊長度為"size"字節(jié)的連續(xù)區(qū)域。函數(shù)的返回值為該區(qū)域的首地址。“類型說明符”表示把該區(qū)域用于何種數(shù)據(jù)類型。(類型說明符*)表示把返回值強制轉(zhuǎn)換為該類型指針。“size”是一個無符號數(shù)。假設shortint型數(shù)據(jù)占2個字節(jié),float型數(shù)據(jù)占4字節(jié)存儲單元,則以下程序段將使pi指向一個shortint類型的存儲單元,使pf指向一個float類型的存儲單元:shortint*pi;float*pf;pi=(short*)malloc(2);pf=(float*)malloc(4);由于在ANSIC中malloc函數(shù)返回的指針為void*(無值型),故在調(diào)用函數(shù)時,必須利用強制類型轉(zhuǎn)換將其轉(zhuǎn)成所需的類型。上面的程序段中,調(diào)用malloc函數(shù)時括號中的*號不可少,否則就轉(zhuǎn)換成普通變量類型而不是指針類型了。在動態(tài)申請存儲空間時,若不能確定數(shù)據(jù)類型所占字節(jié)數(shù),可以使用sizeof運算符來求得。例如:
pi=(int*)malloc(sizeof(int)); pf=(float*)malloc(sizeof(float));這是一種常用的形式。此時將由系統(tǒng)來計算指定類型的字節(jié)數(shù),采用這種形式將有利于程序的移植。8.4.1malloc函數(shù)和free函數(shù)2free函數(shù)格式:free(void*ptr);功能:釋放ptr所指向的一塊內(nèi)存空間,ptr是一個任意類型的指針變量,它指向被釋放區(qū)域的首地址。被釋放區(qū)應是由malloc或calloc函數(shù)所分配的區(qū)域。例8.11分配一塊區(qū)域,輸入一個學生數(shù)據(jù)。main(){
struct
stu{
intnum;char*name;charsex;floatscore;}*ps;
ps=(struct
stu*)malloc(sizeof(struct
stu));
ps->num=102;
ps->name="Zhangping";
ps->sex='M';
ps->score=62.5;
printf("Number=%d\nName=%s\n",ps->num,ps->name);
printf("Sex=%c\nScore=%f\n",ps->sex,ps->score);
free(ps);}運行結(jié)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 現(xiàn)代學生餐廳的照明與色彩搭配藝術(shù)
- 深度解讀網(wǎng)絡輿情的來源與影響研究報告解讀分享
- 現(xiàn)代金融行業(yè)中的移動支付技術(shù)與教育普及
- 快手國慶節(jié)的活動方案
- 國慶假期活動方案
- 國慶節(jié)酒店漲價活動方案
- 2、3、4的乘法口訣(說課稿)-2024-2025學年二年級上冊數(shù)學人教版
- Unit1 There is a horse in this photo(說課稿)-2024-2025學年外研版(三起)四年級上冊001
- 17《他們那時候多有趣啊》(說課稿)-2023-2024學年統(tǒng)編版語文六年級下冊
- 13 我能行(說課稿)-統(tǒng)編版(五四制)道德與法治二年級下冊
- 水利水電工程監(jiān)理平行檢測表部分
- 分部分項工程質(zhì)量檢驗計劃表
- 社區(qū)衛(wèi)生服務中心醫(yī)療服務推薦病-2023版1-4-10
- HY/T 266-2018外壓中空纖維超濾膜表面親水性的測試接觸角法
- GB/T 4857.3-2008包裝運輸包裝件基本試驗第3部分:靜載荷堆碼試驗方法
- 【英文原版小說】the things they carried《負荷》
- 領導干部如何管理壓力與情緒課件
- 2022-2023年度神農(nóng)中華農(nóng)業(yè)科技獎科研和科普類推薦書和摘要表(樣本)
- 《鄉(xiāng)土中國-差序格局》學案-統(tǒng)編版高中語文必修上冊
- 大學成績單中文(word版)
- 海南省儋州市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名明細及行政區(qū)劃代碼居民村民委員會
評論
0/150
提交評論