c語言程序設(shè)計競賽輔導(dǎo)_第1頁
c語言程序設(shè)計競賽輔導(dǎo)_第2頁
c語言程序設(shè)計競賽輔導(dǎo)_第3頁
c語言程序設(shè)計競賽輔導(dǎo)_第4頁
c語言程序設(shè)計競賽輔導(dǎo)_第5頁
已閱讀5頁,還剩90頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、6/15/2020,1,c程序設(shè)計競賽,競賽與考試的區(qū)別,一、注重程序效率,二、信息數(shù)字化,1.數(shù)學(xué)模型提高程序效率,2.算術(shù)技巧提高程序效率,三、數(shù)據(jù)存儲(機試的共同特點),1.狀態(tài)信息數(shù)字化,2.特征信息數(shù)字化,文件操作,3.優(yōu)化數(shù)據(jù)結(jié)構(gòu)提高程序效率,1.數(shù)學(xué)知識提高程序效率,【例1】楊輝三角形的應(yīng)用,求n次二項式各項的系數(shù):已知二項式的展開式為:(a+b)n=Cn0an+Cn1an-1b+Cn2an-2b2+Cnnbn它們共有n+1個系數(shù)。,若你編寫程序用n!/(j!*(n-j)!)計算組合系數(shù)Cnj,會怎樣?,6/15/2020,4,coeff(inta,intn)if(n=1)a1=

2、1;a2=1;elsecoeff(a,n-1)an+1=1for(i=n;i=2;i-)ai=ai+ai-1;a1=1;,程序如下:,main()inta100,i,n;scanf(“%d”,返回,6/15/2020,5,【例2】最大公約數(shù)的應(yīng)用,數(shù)組中有n個數(shù)據(jù),要將它們順序循環(huán)向后移k位,即前面的元素向后移k位,后面的元素則循環(huán)向前移k位,例:1、2、3、4、5循環(huán)移3位后為:3、4、5、1、2??紤]到n會很大,不允許用2*n以上個空間來完成此題。,若題目沒有關(guān)于存儲空間的限制,可以方便地開辟兩個一維數(shù)組,一個存儲原始數(shù)據(jù),另一個存儲移動后的數(shù)據(jù)。,分析1:,6/15/2020,6,程序1

3、如下:,main()inta100,b100,i,n,k;scanf(“%d%d”,6/15/2020,7,分析2:,1)一組循環(huán)移動的情況:通過計算我們可以確定某個元素移動后的具體位置。當(dāng)n=5,k=3時,可計算出14,42,25,53,31的位置,一組移動正好將全部數(shù)據(jù)按要求進行了移動。這樣只需一個輔助變量就可完成整個移動過程。,2)多組循環(huán)移動的情況:,但若把問題就這樣按一組移動去解決,會怎樣?,6/15/2020,8,數(shù)學(xué)模型:,問題與最大公約數(shù)有關(guān),即循環(huán)移動的組數(shù)等于N與K的最大公約數(shù)。這就是利用數(shù)學(xué)知識建模的過程。“感知”是否正確可以通過數(shù)學(xué)方法證明(就象哥德巴赫猜想),或通過程

4、序進行大量數(shù)據(jù)驗證。,1)編寫函數(shù),完成求n,k最大公約數(shù)m的功能2)進行m組循環(huán)移動。3)每組移動,和程序1一樣,通過計算可以確定某個元素移動后的具體位置。在移動之前,用臨時變量存儲需要被覆蓋的數(shù)據(jù)。,實現(xiàn)要點:,6/15/2020,9,程序2如下:,main()inta100,b,i,n,k,m;printf(“inputthenumberofdata”);scanf(“%d”,返回,6/15/2020,10,ff(inta,intb)t=1for(i=2;i=3)num=num+1;printf(“Thenumberof=90is“%d”,num);,程序如下:,對于計算其成績高于90分

5、的課程數(shù)目,應(yīng)如何編寫?,6/15/2020,18,【例2】開燈問題:有從1到n依次編號的n個同學(xué)和n盞燈。1號同學(xué)將所有的燈都關(guān)掉;2號同學(xué)將編號為2的倍數(shù)的燈都打開;3號同學(xué)則將編號為3的倍數(shù)的燈作相反處理(該號燈如打開的,則關(guān)掉;如關(guān)閉的,則打開);以后的同學(xué)都將自己編號的倍數(shù)的燈,作相反處理。問經(jīng)n個同學(xué)操作后,哪些燈是打開的?,6/15/2020,19,1)定義有n個元素的a數(shù)組,它的每個下標(biāo)變量ai視為一燈,i表示其編號。ai=1表示燈處于打開狀態(tài),ai=0表示燈處于關(guān)閉狀態(tài)。2)當(dāng)ai為1時,ai被重新賦為0;當(dāng)ai為0時,ai被重新賦為1。但通過以下算術(shù)運算:ai=1-ai就很

6、好地模擬“開關(guān)”燈的操作。我們把這種形式的賦值語句形象地稱為“乒乓開關(guān)”。,分析:,6/15/2020,20,main()intn,a1000,i,k;printf(“inputanumber”);scanf(“%d”,程序如下:,程序中第二個for循環(huán)i枚舉的不是燈的編號,而是編號為i的同學(xué),其內(nèi)層循環(huán)中,就將包含i因素的燈的編號為“i*k”的燈,改變其狀態(tài)。程序中還用計算省去了用if語句判斷編號能被哪些數(shù)整除的過程。,6/15/2020,21,【例3】右圖中所示的圓圈中,我們把相隔一個數(shù)據(jù)的兩個數(shù)(如1和10,3和5,3和6)稱作是“一對數(shù)”,試編寫程序求出乘積最大的一對數(shù)和乘積最小的一對

7、數(shù)。輸出格式如下:max:?*?=?min:?*?=?其中?表示:找到的滿足條件的數(shù)和乘積。,11716810121651993158126,6/15/2020,22,1)數(shù)據(jù)有前后“位置”關(guān)系,必須用數(shù)組來存儲。數(shù)組定義為anum,則有a0anum-1共num個元素。2)用i代表下標(biāo),題目就是順序?qū)(i-1)與a(i+1)相乘,求出乘積的最大值和最小值即可。3)關(guān)鍵是i=num-1時,保證i+1的“值”是0;當(dāng)i=0時,保證i-1的“值”是num-1,把數(shù)組當(dāng)成圓圈操作通過求余運算很容易實現(xiàn):當(dāng)i=num-1時,(i+1)%num等于0;當(dāng)i=0時(num+i1)%num等于num-1。,

8、實現(xiàn)要點:,6/15/2020,23,4)通過求余運算,便“避免了”判別數(shù)組起點與終點的操作。用變量Max記錄當(dāng)前最大的乘積,m、n為對應(yīng)的兩個乘數(shù);變量min記錄當(dāng)前最小的乘積,s、t為對應(yīng)的兩個乘數(shù)。,6/15/2020,24,程序如下:,main()intmax=1,min=32767,a100,num,i,k,m,n,s,t;printf(“inputanumber”);scanf(“%d”,返回,6/15/2020,25,2)構(gòu)造下標(biāo),【例】請編寫程序統(tǒng)計100人的身高分布,分布等級:180以上、175180、170175、165170、160165、155-160、155以下。,分

9、析:,此類問題表面看不太適合用switch語句來完成。因為即使身高是整數(shù)若不借助數(shù)學(xué)運算至少也有20多種情況,需要20多個case子句。但若注意到每個等級基本是5分一段,通過除法運算將成績(變量sg)除以5后,分支最多也就只有6個了。,6/15/2020,26,main()intsg,k,s7,t;printf(“Input%dheight:”,100);for(k=1;k300)printf(“Inputerror!,Inputagain”);k-;continue;t=sg/5-30;if(t=6)s6=s6+1;t=6;elsest=st+1;,程序如下:,通過計算t=sg/5-30使七

10、類統(tǒng)計區(qū)間與數(shù)組下標(biāo)對應(yīng),提高了程序效率。,這個if語句的功能是什么?,6/15/2020,27,for(t=0;k180:%d”,s6”);break;,返回,1)數(shù)組存儲減少條件判斷,【例1】某次選舉,要從五個候選人(編號分別為1、2、3、4、5)中選一名廠長。請編寫程序完成統(tǒng)計選票的工作。,實現(xiàn)要點:1雖然選票發(fā)放的數(shù)量一般情況下是已知的,但收回的數(shù)量通常是無法預(yù)知的,所以程序采用隨機循環(huán),設(shè)計停止標(biāo)志為“-1”。2統(tǒng)計過程的簡單方法為:先為五個候選人各自設(shè)置五個“計數(shù)器”a,b,c,d,e,然后根據(jù)錄入數(shù)據(jù),通過多分支語句或嵌套條件語句決定為某個“計數(shù)器”累加1。最后輸出統(tǒng)計結(jié)果。,3

11、.優(yōu)化數(shù)據(jù)結(jié)構(gòu)提高程序效率,main()intxp,a,b,c,d,e;a=b=c=d=e=0;printf(inputintegernumber:);scanf(%d,printf(1snumberofvotesis%dn,a);printf(2snumberofvotesis%dn,b);printf(3snumberofvotesis%dn,c);printf(4snumberofvotesis%dn,d);printf(5snumberofvotesis%dn,e);,實現(xiàn)要點:把五個“計數(shù)器”用數(shù)組代替,選票中候選人的編號xp正好做下標(biāo),執(zhí)行Axp=Axp+1就可方便地將選票內(nèi)容累加

12、到相應(yīng)的“計數(shù)器”中。,程序2如下:,返回,程序改進:這樣的程序效率太低,因為程序在執(zhí)行中要進行大量的比較運算。利用數(shù)組做計數(shù)器問題可得到很好的解決。,main()inti,xp,a6;printf(“inputdatauntilinput-1”);scanf(“%d”,【例2】統(tǒng)計找數(shù)字對的出現(xiàn)頻率,算法說明:輸入N(2N100)個數(shù)字(在0與9之間),然后統(tǒng)計出這組數(shù)中相鄰兩數(shù)字組成的鏈環(huán)數(shù)字對出現(xiàn)的次數(shù)。例如:輸入:N=20表示要輸入數(shù)的數(shù)目01598722232787879659輸出:(7,8)=2(8,7)=3指(7,8)、(8,7)數(shù)字對出現(xiàn)次數(shù)分別為2次、3次(7,2)=1(2,

13、7)=1(2,2)=2(2,3)=1(3,2)=1,算法設(shè)計:其實并不是只有一維數(shù)組這樣的數(shù)據(jù)結(jié)構(gòu)可以在算法設(shè)計中有多采的應(yīng)用,根據(jù)數(shù)據(jù)信息的特點,二維數(shù)組的使用同樣可以使算法易于實現(xiàn),此題就正是如此。用10*10的二維數(shù)組(行、列下標(biāo)均為0-9),存儲統(tǒng)計結(jié)果,i行j列存儲數(shù)字對(i,j)出現(xiàn)的次數(shù),無需存儲原始數(shù)據(jù),用其做下標(biāo),在數(shù)據(jù)輸入的同時就能統(tǒng)計出問題的結(jié)果,,main()inta1010,m,i,j,k1,k0;print(“Howmanyisnumbers?”);input(n);print(“Pleaseinputthesenumbers:”);input(k0);for(i=

14、2;i0andaji0)print(“i,j”)=aij,“j,i”=aji),2)數(shù)組使信息有序化,【例1】給1000個職工發(fā)工資,每人的工資從鍵盤輸入。為了保證不要臨時兌換零錢,且取款的張數(shù)最少,取工資前要統(tǒng)計出所有職工的工資所需各種幣值(100,50,20,10,5,2,1元共七種)的張數(shù)。請編寫程序。,當(dāng)題目中的數(shù)據(jù)缺乏規(guī)律時,很難把重復(fù)的工作抽象成循環(huán)不變式來完成,但先用數(shù)組結(jié)構(gòu)存儲這些地信息后,問題就迎刃而解了,,main()inti,j,GZ,A,B8=0,100,50,20,10,5,2,1,S8;for(j=1;j=7;j=j+1)Sj=0;for(i=1;i=0;i=i-1

15、)print(“-”,engai);,例1,【例1】求X,使X2為一個各位數(shù)字互不相同的九位數(shù)。分析:只能用枚舉法嘗試完成此題。由X2為一個九位數(shù),估算X應(yīng)在1000032000之間。,3)記錄狀態(tài)信息,算法設(shè)計:1)用一個10個元素的狀態(tài)數(shù)組p,記錄數(shù)字09在X2中出現(xiàn)的情況。數(shù)組元素都賦初值為1,表示數(shù)字09沒有被使用過。2)對嘗試的每一個數(shù)x,求x*x,并取其各個位數(shù)字,數(shù)字作為數(shù)組的下標(biāo),若對應(yīng)元素為1,則該數(shù)字第一次出現(xiàn),將對應(yīng)的元素賦為0,表示該數(shù)字已出現(xiàn)一次。否則,若對應(yīng)元素為0,則說明有重復(fù)數(shù)字,結(jié)束這次嘗試。3)容易理解當(dāng)狀態(tài)數(shù)組p中有9個元素為0時,就找到了問題的解。但這樣

16、判定有解,需要掃描一遍數(shù)組p。為避免這個步驟,設(shè)置一個計數(shù)器k,在取x*x各個位數(shù)字的過程中記錄不同的數(shù)字的個數(shù),當(dāng)k=9時就找到了問題的解。,main()longx,y1,y2;intp10,2,i,t,k,num=0;for(x=10000;x32000;x=x+1)for(i=0;i=9;i=i+1)pi=1;y1=x*x;y2=y1;k=0;for(i=1;i=9.i=i+1)t=y2mod10;y2=y2/10;if(pt=1)k=k+1;pt=0;elsebreak;if(k=9)num=num+1;print(“No.”,num,“:n=”,x,“n2=”,y1);,【例2】游戲

17、問題:12個小朋友手拉手站成一個圓圈,從某一個小朋友開始報數(shù),報到7的那個小朋友退到圈外,然后他的下一位重新報“1”。這樣繼續(xù)下去,直到最后只剩下一個小朋友,求解這個小朋友原來站在什么位置上呢?,實現(xiàn)要點:首先是如何表示狀態(tài)的問題。開辟12個元素的數(shù)組,記錄12個小朋友的狀態(tài),開始時將12個元素的數(shù)組值均賦為1,表示大家都在圈內(nèi)。這樣小朋友報數(shù)就用累加數(shù)組元素的值來模擬,累加到7時,該元素所代表的小朋友退到圈外,將相應(yīng)元素的值改賦為0,這樣再累加到該元素時和不會改變,又模擬了已出圈外的狀態(tài)。,main()inta100,i,k,p,m;printf(“inputnumbersofgame:”)

18、;scanf(“%d”,其中n表示做游戲的總?cè)藬?shù),k表示開始及狀態(tài)數(shù)組的下標(biāo)變量,m表示退出圈外的報數(shù)點,即報m的人出隊,p表示已退出圈外的人數(shù)。,程序如下:,p=0;while(pn)k=1;x=x+ak;printf(“%d”,k);ak=0;p=p+1;for(i=1;in時,賦k=1,表示n號報完數(shù)就該1號報數(shù)。模擬了將n個人連成了一個“圈”的情況。2、x為“報”出的數(shù),x=m時輸出退出圈外人的下標(biāo)k,將ak賦值為0;3、p=n-1時游戲結(jié)束;4、最后檢測還在圈上ai=1的人,輸出其下標(biāo)值即編號。,返回,48,二、信息數(shù)字化1.狀態(tài)信息數(shù)字化,1)提高效率【例1】冒泡排序算法的改進,分

19、析:,冒泡排序算法的基本思想就是:相鄰數(shù)據(jù)比較若逆序則交換,逐漸將小數(shù)據(jù)冒到數(shù)組的前面,大的數(shù)據(jù)則沉到數(shù)組的后面,從而完成排序工作。,6/15/2020,49,數(shù)據(jù)原本有序的概率并不高,但經(jīng)過少于n-1趟操作后,數(shù)據(jù)已經(jīng)有序的概率卻非常高。為提高效率,可以對冒泡排序算法進行改進,當(dāng)發(fā)現(xiàn)某趟沒有交換后就停止下一趟的比較操作。用標(biāo)志量來記錄每趟交換數(shù)據(jù)的情況,如flag=0表示沒有進行過交換,一但有數(shù)據(jù)進行交換則置flag為1,表示已進行過交換。當(dāng)一趟比較交換完成后,若flag仍為0時,則無需進行下一趟操作,否則若flag為1時,只能繼續(xù)進行下一趟操作。,6/15/2020,50,main()in

20、ti,j,t,n,a100,flag;printf(“inputdatanumber(=i;j-)if(ajaj-1)t=aj;aj=aj-1;aj-1=t;flag=1;for(i=0;in;i+)printf(%d,ai);,改進后的程序如下:,返回,6/15/2020,51,程序說明:,1)排序前“for(i=1;iy,6/15/2020,57,for(i=2;i=x0;i+)flag=1;while(flag)flag=0;if(x1%i=0)x1=x1/i;flag=1;if(x2%i=0)x2=x2/i;flag=1;if(x3%i=0)x3=x3/i;flag=1;if(flag

21、=1)t=t*i;x0=max(x1,x2,x3);printf(“Theresultis%dn”,t);,返回,6/15/2020,58,2.特征信息數(shù)字化,1)邏輯類問題,【例1】警察局抓了a,b,c,d四名偷竊嫌疑犯,其中只有一人是小偷。審問中a說:“我不是小偷?!眀說:“c是小偷?!眂說:“小偷肯定是d?!眃說:“c在冤枉人。”現(xiàn)在已經(jīng)知道四個人中三人說的是真話,一人說的是假話,問到底誰是小偷?,6/15/2020,59,實現(xiàn)要點:,用變量x存放小偷的編號,則x的取值范圍從1取到4,就嘗試了他們中的某人是小偷的所有情況。四個人所說的話就可以分別寫成:a說的話:x!=1b說的話:x=3c

22、說的話:x=4d說的話:x!=4或not(x=4)注意利用前面學(xué)習(xí)到的技巧,在x的枚舉過程中,當(dāng)這四個邏輯式的值相加等于3時,即表示“四個人中三人說的是真話,一人說的是假話”,所以以此為定解條件。,分析:,將a,b,c,d將四個人進行編號,號碼分別為1,2,3,4。則問題可用枚舉嘗試法來解決。,6/15/2020,60,程序如下:,main()intx;for(x=1;x=4;x+)if(x!=1)+(x=3)+(x=4)+(x!=4)=3)printf(“%cisathief.”,chr(64+x);,運行結(jié)果:cisathief.,程序說明:,為了程序的方便運行我們對人名進行了數(shù)字化,但結(jié)

23、果的形式還要符合題目的描述,所以輸出時,將數(shù)字轉(zhuǎn)化為對應(yīng)的字母。這個程序可以方便的改寫成PASCAL或BASIC程序,就C語言而言程序還可直接寫成如下形式:,6/15/2020,61,main()intx;for(x=a;x=d;x+)if(x!=a)+(x=c)+(x=d)+(x!=d)=3)printf(“%cisathief.”,x);,6/15/2020,62,【例2】三位老師對某次數(shù)學(xué)競賽進行了預(yù)測。他們的預(yù)測如下:甲說:學(xué)生A得第一名,學(xué)生B得第三名。乙說:學(xué)生C得第一名,學(xué)生D得第四名。丙說:學(xué)生D得第二名,學(xué)生A得第三名。競賽結(jié)果表明,他們都說對了一半,說錯了一半,并且無并列名

24、次,試編寫程序輸出A、B、C、D各自的名次。,6/15/2020,63,分析:,用數(shù)1,2,3,4分別代表學(xué)生a,b,c,d獲得的名次。問題就可以利用三重循環(huán)把所有的情況枚舉出來。程序如下:,返回,6/15/2020,64,main()inta,b,c,d;for(a=1;a=4;a+)for(b=1;b=4;b+)if(a!=b)for(c=1;c=4;c+)if(c!=a,運行結(jié)果:a=4,b=3,c=1,d=2,6/15/2020,65,實現(xiàn)要點:,【例1】填寫運算符輸入任意5個數(shù)x1,x2,x3,x4,x5每相鄰兩個數(shù)之間填上一個運算符+、-、*或/。在填入四個運算符后,使得表達式值為

25、一個指定值y(y由鍵盤輸入)。求出所有滿足條件的表達式。,模仿人去試填所有的運算符,結(jié)果是什么,2)智巧類問題,?,1)枚舉法解題2)若當(dāng)前運算符輪到/則運算符右端的數(shù)必須非零,因為零不能當(dāng)除數(shù)。,6/15/2020,66,3)現(xiàn)在接著考慮+、-、*、/應(yīng)如何表示,才能方便程序?qū)Ρ磉_式的求值?4)如何處理“先乘除/后加減”的優(yōu)先順序?,模擬計算:,f-減去標(biāo)志。減法運算時,置f=-1,否則f=1;q-若當(dāng)前運算符為+(-)時,q存貯運算符的左項值;若當(dāng)前運算符為*(/)時,q存貯兩數(shù)乘(除)后結(jié)果;p-累加器。每填一個算符p=p+f*q。,為了解決運算的優(yōu)先級問題,我們設(shè)置如下變量:,6/15

26、/2020,67,程序如下:,main()intj,k,f,i5,total;floatn6,p,q;charc5=,+,-,*,/;printf(“ninputfivenumber”);for(j=1;j=5;j+)scanf(“%f”,1.四個for循環(huán)后的四個if語句的作用是什么?2.四個數(shù)組元素i1、i2、i3、i4代表四個運算符,定義的作用是什么?,6/15/2020,68,for(k=1;k=4;k+)switch(ik)case1:p=p+f*q;f=1;q=nk+1;break;case2:p=p+f*q;f=-1;q=nk+1;break;case3:q=q*nk+1;bre

27、ak;case4:q=q/nk+1;if(p+f*q=n0)total+;printf(“ntotal:%5d:”,total);for(k=1;k=4;k+)printf(“%f%c”,nk,cik);printf(“%f=%f”,n5,n0);if(total%20=0)每20個方案為一屏,逐屏顯示printf(“pressentertocontinue”);getchar();,6/15/2020,69,【例2】有10箱產(chǎn)品每箱有1000件,正品每件100克。其中的幾箱是次品,次品每件比正品輕10克,問能否用秤只稱一次,就找出哪幾箱是次品。,程序如下:,main()inti,k,n,w1

28、=0,w2=0,t=1;printf(“nInputthenumberofboxes:”);scanf(“%ld”,6/15/2020,70,w1=w1*100;printf(“nnormalweight%d”,w1);printf(“nInputrealityweight”);scanf(“%ld”,6/15/2020,71,【例3】編寫程序?qū)斎氲囊粋€整數(shù),判斷它能否被3,5,7整除,并輸出以下信息之一:1)能同時被3,5,7整除;2)能被其中兩數(shù)(要指出哪兩個)整除;3)能被其中一個數(shù)(要指出哪一個)整除;4)不能被3,5,7任一個整除。,6/15/2020,72,switch(k)ca

29、se3:printf(“nAll”);break;case2:printf(“ntwo”);break;case1:printf(“none”);break;case0:printf(“nnone“);break;,程序1:,main()longn;intk;printf(“nPleaseenteranumber:”);scanf(“%1d”,k=(n%3=0)+(n%5=0)+(n%7=0),6/15/2020,73,程序2:,main()longn;intk;printf(“nPleaseenteranumber:”);scanf(“%1d”,k=(n%3=0)+(n%5=0)*2+(n%

30、7=0)*4,6/15/2020,74,程序中k表示整除的情況值。程序1中,k的范圍是03可以表示四種情況,而程序2中,為k賦值的表達式是:(n%3=0)+(n%5=0)*2+(n%7=0)*4,k的范圍是07可以表示八種情況。,switch(k)case7:printf(“nAll”);bresk;case6:printf(“n5and7is”);break;case5:printf(“n3and7is”);break;case4:printf(“n7is”);break;case3:printf(“n3and5is”);break;case2:printf(“n5is”);break;ca

31、se1:printf(“n3is”);break;case0:printf(“nnone“);break;,程序說明:,返回,6/15/2020,75,三、文件,1.C語言文件概述,存儲在外存儲器上一組相關(guān)數(shù)據(jù)集合稱為“文件”每個文件都有一個文件名,OS廣義的文件,狹義的文件數(shù)據(jù)文件程序的處理的數(shù)據(jù)(輸入)和結(jié)果(輸出),6/15/2020,76,從文件存儲的方式來看,文件可分為:ASCII碼文件和二進制碼文件兩種,ASCII文件也稱為文本文件,這種文件在磁盤中存放時每個字符對應(yīng)一個字節(jié),用于存放對應(yīng)的ASCII碼。,二進制文件是按二進制的編碼方式來存儲文件的。,輸入輸出字符流的開始和結(jié)束,只

32、由程序控制而不受物理符號的控制。則把這種文件稱作“流式文件”。,77,2.文件的打開與關(guān)閉,1)文件指針,文件在進行讀、寫操作之前要先打開,使用完畢后要關(guān)閉。,打開文件實際上是建立文件的各種有關(guān)信息,并使文件指針指向該文件,以便進行其它操作。,關(guān)閉文件則是斷開指針與文件之間的聯(lián)系,也就禁止再對該文件進行操作。,6/15/2020,78,用一個指針變量指向一個文件,這個指針稱為文件指針。通過文件指針就可對它所指的文件進行各種操作。,定義文件指針的一般形式為:,FILE*指針變量標(biāo)識符;,2)文件的打開,就是打開外存數(shù)據(jù)進入內(nèi)存的通道,并分配一定的內(nèi)存空間存儲進行內(nèi)存中的文件數(shù)據(jù)。,6/15/20

33、20,79,fopen()函數(shù)用來打開一個文件,一般形式為:,文件指針名=fopen(文件名,使用文件方式);,對于文件使用方式有以下幾點說明:,1)文件使用方式由r,w,a,t,b,+六個字符拼成,各字符的含義是:,r(read):讀w(write):寫a(append):追加t(text):文本文件,可省略不寫b(banary):二進制文件+:讀和寫,2)凡用“r”打開一個文件時,該文件必須已經(jīng)存在,且只能從該文件讀出。,3)用“w”打開的文件只能向該文件寫入。若打開的文件不存在,則以指定的文件名建立該文件,若打開的文件已經(jīng)存在,則將該文件已有信息刪去,重建一個新文件。,4)若要向一個已存

34、在的文件追加新的信息,只能用“a”方式打開文件。(該文件必須存在),5)在打開一個文件時,如果出錯,fopen將返回一個空指針值NULL。,6/15/2020,81,3)文件的關(guān)閉,關(guān)閉文件的操作是由函數(shù)fclose()實現(xiàn)的,一般形式是:,fclose(文件指針);,正常完成關(guān)閉文件操作時,fclose函數(shù)返回值為0。如返回非零值則表示有錯誤發(fā)生。,RETURN,6/15/2020,82,3文件的讀寫,字符讀寫函數(shù):fgetc和fputc字符串讀寫函數(shù):fgets和fputs數(shù)據(jù)塊讀寫函數(shù):freed和fwrite格式化讀寫函數(shù):fscanf和fprinf,1字符讀寫函數(shù)fgetc和fput

35、c,字符讀寫函數(shù)是以字符(字節(jié))為單位的讀寫函數(shù)。每次可從文件讀出或向文件寫入一個字符。,1)讀字符函數(shù)fgetc(),fgetc函數(shù)的功能是從指定的文件中讀一個字符,形式為:,字符變量=fgetc(文件指針);,6/15/2020,83,【注意事項】,在fgetc函數(shù)調(diào)用中,讀取的文件必須是以讀或讀寫方式打開的。,讀取字符的結(jié)果也可以不向字符變量賦值。,在文件內(nèi)部有一個位置指針。用來指向文件的當(dāng)前讀寫字節(jié)。,文件系統(tǒng)在文件的末尾存儲了一個結(jié)束標(biāo)志EOF,表文件中的字符已讀“完”了。,6/15/2020,84,2)寫字符函數(shù)fputc,fputc函數(shù)的功能是把一個字符寫入指定的文件中,形式為:

36、,fputc(字符,文件指針);,【注意事項】,被寫入的文件可以用寫、讀寫、追加方式打開,用寫或讀寫方式打開一個已存在的文件時將清除原有的文件內(nèi)容,寫入字符從文件首開始。,每寫入一個字符,文件內(nèi)部位置指針向后移動一個字節(jié)。,fputc函數(shù)有一個返回值,如寫入成功則返回寫入的字符,否則返回一個EOF。,6/15/2020,85,2字符串讀寫函數(shù)fgets和fputs,1)讀字符串函數(shù)fgets,功能是從指定的文件中讀一個字符串到字符數(shù)組中,形式為:,fgets(字符數(shù)組名,n,文件指針);,【注意事項】,在讀出n-1個字符之前,如遇到了換行符或EOF,則讀出結(jié)束。,fgets函數(shù)也有返回值,其返

37、回值是字符數(shù)組的首地址。,6/15/2020,86,2)寫字符串函數(shù)fputs,功能是向指定的文件寫入一個字符串,形式為:,fputs(字符串,文件指針);,3數(shù)據(jù)塊讀寫函數(shù)fread和fwtrite,讀數(shù)據(jù)塊函數(shù)調(diào)用的一般形式為:,fread(buffer,size,count,fp);,寫數(shù)據(jù)塊函數(shù)調(diào)用的一般形式為:,fwrite(buffer,size,count,fp);,6/15/2020,87,其中:buffer是一個指針,在fread函數(shù)中,它表示存放輸入數(shù)據(jù)的首地址;在fwrite函數(shù)中,它表示存放輸出數(shù)據(jù)的首地址。size表示數(shù)據(jù)塊的字節(jié)數(shù)。count表示要讀寫的數(shù)據(jù)塊塊數(shù)。fp表示文件指針。,4格式化讀寫函數(shù)fscanf和fprintf,fscanf(文件指針,格式字符串,輸入表列);,fpr

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論