華中科技大學(xué)c語言實(shí)驗(yàn)報(bào)告_第1頁
華中科技大學(xué)c語言實(shí)驗(yàn)報(bào)告_第2頁
華中科技大學(xué)c語言實(shí)驗(yàn)報(bào)告_第3頁
華中科技大學(xué)c語言實(shí)驗(yàn)報(bào)告_第4頁
華中科技大學(xué)c語言實(shí)驗(yàn)報(bào)告_第5頁
已閱讀5頁,還剩202頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

譯中科技大孚課程實(shí)驗(yàn)報(bào)告課程名稱: C語言程序設(shè)計(jì)專業(yè)班級(jí):計(jì)算機(jī)科學(xué)與技術(shù)1234班學(xué)號(hào): U123412345姓名: OOO指導(dǎo)教師: O。O報(bào)告日期: OOOO年。月O日計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院目錄TOC\o"1-5"\h\z\o"CurrentDocument"實(shí)驗(yàn)1表達(dá)式和標(biāo)準(zhǔn)輸入與輸出實(shí)驗(yàn) 1\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?1\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 1\o"CurrentDocument"自設(shè)題 12\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 14\o"CurrentDocument"實(shí)驗(yàn)2流程控制實(shí)驗(yàn) 15\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?15\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 15\o"CurrentDocument"自設(shè)題 29\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 34\o"CurrentDocument"實(shí)驗(yàn)3函數(shù)與程序結(jié)構(gòu)實(shí)驗(yàn) 35\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?35\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 35\o"CurrentDocument"自設(shè)題 49\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 53\o"CurrentDocument"實(shí)驗(yàn)4編譯預(yù)處理實(shí)驗(yàn) 54\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?54\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 54\o"CurrentDocument"自設(shè)題 67\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 69\o"CurrentDocument"實(shí)驗(yàn)5數(shù)組實(shí)驗(yàn) 70\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?70\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 70\o"CurrentDocument"自設(shè)題 96\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 97\o"CurrentDocument"實(shí)驗(yàn)6指針實(shí)驗(yàn) 98\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?98\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 98\o"CurrentDocument"自設(shè)題 123\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 127\o"CurrentDocument"實(shí)驗(yàn)7結(jié)構(gòu)與聯(lián)合實(shí)驗(yàn) 128\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?128\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 128\o"CurrentDocument"自設(shè)題 171\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 177\o"CurrentDocument"實(shí)驗(yàn)8文件實(shí)驗(yàn) 178\o"CurrentDocument"實(shí)驗(yàn)?zāi)康?178\o"CurrentDocument"實(shí)驗(yàn)內(nèi)容及要求 178\o"CurrentDocument"自設(shè)題 188\o"CurrentDocument"實(shí)驗(yàn)小結(jié) 190\o"CurrentDocument"參考文獻(xiàn) 191實(shí)驗(yàn)1表達(dá)式和標(biāo)準(zhǔn)輸入與輸出實(shí)驗(yàn)1.1實(shí)驗(yàn)?zāi)康?1)熟練掌握各種運(yùn)算符的運(yùn)算功能,操作數(shù)的類型,運(yùn)算結(jié)果的類型及運(yùn)算過程中的類型轉(zhuǎn)換,重點(diǎn)是C語言特有的運(yùn)算符,例如位運(yùn)算符,問號(hào)運(yùn)算符,逗號(hào)運(yùn)算符等;熟記運(yùn)算符的優(yōu)先級(jí)和結(jié)合性。(2)掌握getchar,putchar,scanf和printf函數(shù)的用法。(3)掌握簡單C程序(順序結(jié)構(gòu)程序)的編寫方法。(4)掌握書寫實(shí)驗(yàn)報(bào)告的格式與基本要求。1.2實(shí)驗(yàn)內(nèi)容及要求源程序改錯(cuò)下面給出了一個(gè)簡單C語言程序例程,用來完成以下工作:(1)輸入華氏溫度f,將它轉(zhuǎn)換成攝氏溫度C后輸出;(2)輸入圓的半徑值r,計(jì)算并輸出圓的面積s;(3)輸入短整數(shù)k、p,將k的高字節(jié)作為結(jié)果的低字節(jié),p的高字節(jié)作為結(jié)果的高字節(jié),拼成一個(gè)新的整數(shù),然后輸出;在這個(gè)例子程序中存在若干語法和邏輯錯(cuò)誤。要求在計(jì)算機(jī)上對這個(gè)例子程序進(jìn)行調(diào)試修改,使之能夠正確完成指定任務(wù)。#include<stdio.h>#definePI3.14159;intmain(void)4{intf;shortp,k;doublec,r,s;/*fortask1*/printf(€€InputFahrenheit:'');scanfT%d'',f);c=5/9*(f-32);print"“\n%d(F)=%.2f(C)\n\n”,f,c);13/*fortask2*/printfpinputtheradiusr:n);scanf(n%ff,&r);s=PI*r*r;printf(M\nTheacreageis%.2f\n\nM,&s);/*fortask3*/printfpinputhexintk,p:");scanf(n%x%x”,&k,&p);21newint=(p&0xff00)|(k&0xfTO0)?8;printf(Mnewint=%x\n\n°,newint);return0;24}解答:(1)錯(cuò)誤修改:1)第2行的符號(hào)常量定義后不能有分號(hào),正確形式為:#definePI3.141592)第3行的intmain(void)返回值類型和函數(shù)名應(yīng)分開,正確形式為:intmain(void)3)第10行的scanf("%d”,f);在輸入內(nèi)容時(shí)指向地址應(yīng)使用&,正確形式為:scanf("%d”,&f)4)第11行的c=5/9*(f-32);由于f是int型,在運(yùn)算時(shí)右側(cè)表達(dá)式會(huì)被截去小數(shù)部分,正確形式為:c=5.0/9*(&32);5)第12行的printf(41\n%d(F)=%.2f(C)\n\n”,f,c);由于c被定義為雙精度浮點(diǎn)數(shù)應(yīng)使用占位符%If,正確形式為:prints"\n%d(F)=%.21f(C)\n\n”,f,c);6)第15行的scanf("%f',&r);由于r被定義為雙精度浮點(diǎn)數(shù)應(yīng)使用占位符%If,正確形式為:scanfi["%lf,,&r);7)第17行的prints"\nTheacreageis%.2f\n\n",&s);由于s被定義為雙精度浮點(diǎn)數(shù)應(yīng)使用占位符%If,正確形式為:printfl^"\nTheacreageis%.21f\n\n",&s);8)第17行的printf("\nTheacreageis%.2f\n\n",&s);在printf中不涉及對s的修改,應(yīng)不用&,正確形式為:prints"\nTheacreageis%.21f\n\n",s);9)第20行的scanf("%x%x",&k,&p);由于k,p被定義為短整數(shù),占位符應(yīng)使用%hx,正確形式為:scanff%hx%hx",&k,&p);10)第21行的newint=(p&0xfR)0)|(k&0xflro0)?8中使用了一個(gè)未聲明的變量newint,應(yīng)在使用前聲明,正確形式為:(6)shortp,k,newint;(注意,改動(dòng)針對第六行)11)第21行的newint=(p&0xfTO0)|(k&0xffD0)<<8忽略了運(yùn)算順序,應(yīng)恰當(dāng)使用括號(hào)改變運(yùn)算順序,正確形式為:newint=(p&0xflTO0)|((k&0xflTO0)<<8);12)第21行的newint=(p&0xfTO0)|(k&0xflTO0)<<8位運(yùn)算邏輯有誤,應(yīng)恰當(dāng)改變運(yùn)算方式,正確形式為:newint=(p&0x1TO0)|((k&0x1TO0)?8);13)第22行的printff'newint=%x\n\n",newint);由于newint被定義為短整數(shù),占位符應(yīng)使用%hx,正確形式為:printf("newint=%hx\n\n",newint);(2)錯(cuò)誤修改后運(yùn)行結(jié)果:見圖1-1(查閱資料知1華氏度確為-17.22攝氏度;半徑為2的圓面積在保留2位小數(shù)且n取3.14159時(shí)面積確為12.57;將a2cd的高字節(jié)作為結(jié)果的低字節(jié),a3a3的高字節(jié)作為結(jié)果的高字節(jié),拼成一個(gè)新的整數(shù),這樣的確得到a3a2,其中采用16進(jìn)制是為了表達(dá)與驗(yàn)證方便)InputPahrenheit:11<F>--17.22<C>inputtheradiusi*:2Theacreayeis12.57inputhexintk.p:a2cda3a3newint-a3a2圖1-1源程序改錯(cuò)的運(yùn)行結(jié)果1.2.2源程序修改替換下面的程序利用常用的中間變量法實(shí)現(xiàn)兩數(shù)交換,請改用不用第三個(gè)變量的交換法實(shí)現(xiàn)。#include<stdio.h>intmain(){inta,b,t;print/'Inputtwointegers:^^);scanfT%d%d,,,&a,&b);t=a,a=b,b=t;prinfC'\na=%d,b=%d”,a,b);return0;}解答:由于只能使用兩個(gè)變量,我們需要利用一個(gè)變量來保存兩個(gè)數(shù)的一些共同特征,而這些特征要能通過一定的運(yùn)算返回初始的數(shù),而若把兩數(shù)之和存放于第一個(gè)數(shù)中,通過依次均減去第二個(gè)數(shù),可在恢復(fù)原來的數(shù)的同時(shí)將它們交換順序。替換后的程序如下所示:#include<stdio.h>intmain()(inta,b;printffTnputtwointegers:");scanf^s(n%d%dn,&a,&b);a=a4-b;b=a-b;a=a-b;printf("\na=%d,b=%d",a,b);return0;運(yùn)行結(jié)果見圖1-2(1,2交換位置后確為2,1)InputtMointegers:12a-2,!>-1圖1-2源程序修改替換題的運(yùn)行結(jié)果1.2.3程序設(shè)計(jì)(1)編寫一個(gè)程序,輸入字符C,如果C是大寫字母,則將C轉(zhuǎn)換成對應(yīng)的小寫,否則C的值不變,最后輸出C。解答:首先,無論輸入什么字符,這個(gè)字符均具有相應(yīng)的ASCII碼,所以我們無需檢測輸入是否合理,而在接受這個(gè)輸入之后,我們需要根據(jù)它的ASCII碼來判斷它是否為大寫字母,如果它是大寫字母,那么就把它變?yōu)樾懽帜?減去A與a的ASCH碼值之差即可實(shí)現(xiàn)這個(gè)要求),而若該字符不滿足該要求,直接原樣輸出即可,算法見流程圖1-1,其余細(xì)節(jié)見程序注釋,程序如下。流程圖1-1程序設(shè)計(jì)題1的算法#include<stdio.h>intmain()intc;printf("輸入字符,如果它是大寫字母,則將它轉(zhuǎn)換成對應(yīng)的小寫,否則原樣輸出:");c=getchar();〃通過getchar()來獲得字符對應(yīng)的ASCII碼if(c<='Z'&&c>='A') 〃判斷是否為大寫字母c=c-('A'-'a');〃大寫字母變小寫printf("處理結(jié)果是:%c",c);return0;)測試:由于本題不涉及無效輸入,所以我們只需分析程序的幾種運(yùn)行情況,其中可分為對大寫字母進(jìn)行轉(zhuǎn)化為相對應(yīng)的小寫字符;而對于小寫字母而言,程序不應(yīng)該將其進(jìn)行任何轉(zhuǎn)化;此外,對于非字母輸入我們也不應(yīng)該轉(zhuǎn)化,具體測試數(shù)據(jù)見表1-1,測試結(jié)果見圖1-3?1-5。表1-1編程題1的測試數(shù)據(jù)測試用例程序輸入理論結(jié)果運(yùn)行結(jié)果用例1Eee用例2eee用例3111對應(yīng)測試測試用例1的運(yùn)行結(jié)果如圖1-3所示輸入字符,如果它是大寫字母,則將它轉(zhuǎn)換成對應(yīng)的小寫,否則原樣輸出:E見或結(jié)果是:e圖1-3編程題1的測試用例一的運(yùn)行結(jié)果對應(yīng)測試測試用例2的運(yùn)行結(jié)果如圖14所示。盤翥矗如既是大寫字母’則將垂挨成對應(yīng)的小弓否則原樣輸出一圖1-4編程題1的測試用例二的運(yùn)行結(jié)果對應(yīng)測試測試用例3的運(yùn)行結(jié)果如圖1-5所示。輸入字符,如果它是大寫字母,則將它轉(zhuǎn)換成對應(yīng)的小寫,否則原樣輸出:1七里結(jié)果是:1圖1-5編程題1的測試用例三的運(yùn)行結(jié)果說明上述的運(yùn)行結(jié)果與理論分析吻合,驗(yàn)證了程序的正確性。(2)編寫一個(gè)程序,輸入無符號(hào)短整數(shù)x,m,n(0<m<15,1<n<16-m),取出x從第m位開始向左的n位(m從右至左編號(hào)為0?15),并使其向左端(第15位)靠齊。解答:由于題目中明確要求輸入無符號(hào)短整數(shù),且目前我們?nèi)鄙贆z查輸入是否為整數(shù)的手段,所以本題并不檢查輸入的x是否合理;不過以我們目前的知識(shí),我們可以根據(jù)題目要求對輸入的m,n是否合理進(jìn)行檢查(僅檢查它們是否在合理范圍內(nèi),默認(rèn)其為整數(shù))。而在確認(rèn)輸入合理之后,我們著手開始對問題進(jìn)行處理,由于這是一個(gè)涉及到計(jì)算機(jī)內(nèi)部數(shù)據(jù)的二進(jìn)制運(yùn)算的問題,相應(yīng)地,我們在解決這個(gè)問題時(shí)也要利用C語言提供的位運(yùn)算來完成相應(yīng)的操作,首先,由于我們只需要x從第m位開始向左的n位,所以我們需要去掉x的其余部分(第m位之前的內(nèi)容),同時(shí)從第m位開始向左的n位之后的內(nèi)容也不再被需要,所以我們也將其去除。至于這去除的實(shí)現(xiàn),為防止數(shù)據(jù)的丟失,我們不應(yīng)直接對x進(jìn)行操作,而應(yīng)對我們之后會(huì)用到的邏輯尺進(jìn)行操作,而有關(guān)邏輯尺的操作,我們可先使用十六進(jìn)制數(shù)對其賦值,使其全為KOxffff,這樣較將0取反更方便),再進(jìn)行相應(yīng)的左移與右移(注意在移動(dòng)時(shí)要分開進(jìn)行,否則會(huì)由于編譯器對運(yùn)算的簡化使部分該被清0的位保留為1),而后,我們再用我們?nèi)〉玫倪壿嫵吲cx進(jìn)行按位與運(yùn)算,即可取出x中相應(yīng)的二進(jìn)制位,之后,再根據(jù)題目的要求,把x移動(dòng)到指定的位置,最后,由于題目中使用的數(shù)字均為十進(jìn)制數(shù),所以我們的輸入與輸出均采用十進(jìn)制數(shù)進(jìn)行。其余細(xì)節(jié)見程序注釋,算法見流程圖1-2,程序如下。#include<stdio.h>intmain()unsignedshortintx,m,n,i;printf("輸入x(10進(jìn)制)、m(0-15)和n(1?16-m):”);scanf(n%hu%hu%huH,&x,&m,&n);if(m>=0&&m<=15&&n>=1&&n<=l6-m)〃判斷輸入是否合理{i=Oxffff; 〃準(zhǔn)備位運(yùn)算所需邏輯尺i?=m; //確定變換起始位置i?=16-n; 〃確定變換作用長度i?=16-m-n;〃進(jìn)入變換位置/*注意在移動(dòng)時(shí)要分開進(jìn)行,否則會(huì)由于編譯器對運(yùn)算的簡化使部分該被清。的位保留為1*/x&=i;x?=16-m-n;〃左移printf("經(jīng)過變換得到:%hu",x);}elseprintf("輸入錯(cuò)誤,請檢查您的輸入)〃提示輸入不合理return0;流程圖1-2程序設(shè)計(jì)題2的算法測試:由于本題中涉及了對錯(cuò)誤輸入的排除,所以我們需要對程序能否正確排除這些錯(cuò)誤的輸入進(jìn)行測試,同時(shí),我們也需要對程序的基本功能進(jìn)行檢查,不過由于本題涉及到位運(yùn)算,這使得對結(jié)果的驗(yàn)證較為困難,我們需要合理的設(shè)計(jì)測試數(shù)據(jù)并將其轉(zhuǎn)化二進(jìn)制數(shù)以供驗(yàn)證,再將所得的二進(jìn)制數(shù)轉(zhuǎn)為十進(jìn)制數(shù)并程序輸出的十進(jìn)制數(shù)進(jìn)行比對,以驗(yàn)證程序的正確性(即使采用十六進(jìn)制輸入輸出也不夠結(jié)果也不是十分顯然,故不采用),測試數(shù)據(jù)見表1-2,測試結(jié)果見圖1?6?1-8。表1-2編程題2的測試數(shù)據(jù)或試厚孑物入3論逑累運(yùn)行逑MSWXmNumi0000000000011001(25)3,H-MigMllOOOeOOOOOO0000K49152的1521101010110000011(54659)161勒入槽次:m(aeTs3?檢資臉入用的31101010110000011C54659)135輸入Cn(ft£^3)位交帔入對應(yīng)測試測試用例1的運(yùn)行結(jié)果如圖1-6所示輸入x(10進(jìn)制)、m15)和n([?16-e):2532遂過變換得至49152圖1-6編程題2的測試用例一的運(yùn)行結(jié)果對應(yīng)測試測試用例2的運(yùn)行結(jié)果如圖1-7所示。輸入X(10進(jìn)制)、m(0?15)和n(1?16-m):54659161輸入錯(cuò)誤,請密查您的輸入圖1-7編程題2的測試用例二的運(yùn)行結(jié)果對應(yīng)測試測試用例3的運(yùn)行結(jié)果如圖1-8所示。輸入x(1。進(jìn)制)、m(0?15)和n(1?16-m):54659135強(qiáng)入錯(cuò)誤,請愈查您的輸入圖1-8編程題2的測試用例三的運(yùn)行結(jié)果說明上述的運(yùn)行結(jié)果與理論分析吻合,驗(yàn)證了程序的正確性。(3)IP地址通常是4個(gè)用句點(diǎn)分隔的小整數(shù)(即點(diǎn)分十進(jìn)制),如32.55.1.102o這些地址在機(jī)器中用無符號(hào)長整形表示。編寫一個(gè)程序,以機(jī)器存儲(chǔ)的形式讀入一個(gè)互聯(lián)網(wǎng)1P地址,對其譯碼,然后用常見的句點(diǎn)分隔的4部分的形式輸出。例如,整形676879571二進(jìn)制表示就是:00101000010110000101110011010011,按照8位一組可表示為:408892211,由于CPU處理數(shù)據(jù)的差異,它的順序是顛倒的,所有最終格式為211.92.88.40。解答:首先,這依然是一個(gè)涉及到位運(yùn)算的題目,所以我們依然會(huì)用到按位操作與邏輯尺,而邏輯尺的制備與使用均與我們在程序設(shè)計(jì)題2中所使用的方法大體相同,例如我們使用十六進(jìn)制數(shù)制取邏輯尺,同時(shí)盡管從原理上說,我們只需要一個(gè)邏輯尺(在每次使用后對其進(jìn)行移動(dòng)即可),但這樣寫成的程序不夠明To而在取得了邏輯尺之后,我們再進(jìn)行按位與運(yùn)算,以達(dá)到取出各二進(jìn)制位的效果。不過,本題與程序設(shè)計(jì)題2的不同之處在于,我們需把取出的數(shù)進(jìn)行移動(dòng)的位數(shù)是固定的,但需要注意的時(shí),正如題目中所提到的由于CPU處理數(shù)據(jù)的差異,我們需要將我們?nèi)〕龅臄?shù)據(jù)進(jìn)行重新排序,而且,由于我們輸出的是IP地址,所以我們需要在輸出中添加相應(yīng)的句點(diǎn)。此外,盡管本題中可能出現(xiàn)非數(shù)字輸入,但由于我們目前沒有有效的手段進(jìn)行檢測,所以我們默認(rèn)所有的輸入都是合理的。其余細(xì)節(jié)見程序注釋,算法見流程圖1-3,程序如下。輸入無符e長整形數(shù)中流程圖1-3程序設(shè)計(jì)題3的算法#include<stdio.h>intmain()iounsignedlongintip,m1,m2,m3,m4,p1,p2,p3,p4;printf("輸入長整數(shù)形式的ip地址:");scanf("%lu",&ip);ml=OxflTOOOOOO;〃各分段邏輯尺m2=OxOOffDOOO;//各分段邏輯尺m3=OxOOOOfTOO;//各分段邏輯尺m4=OxOOOOOOff;〃各分段邏輯尺pl=(ip&ml)?24;//取出各部分二進(jìn)制數(shù)p2=(ip&m2)?16;〃取出各部分二進(jìn)制數(shù)p3=(ip&m3)?8;//取出各部分二進(jìn)制數(shù)p4=(ip&m4);〃取出各部分二進(jìn)制數(shù)printf("這個(gè)ip地址常規(guī)形式為:%lu.%lu.%lu.%lu",p4,p3,p2,pl);//按要求格式輸出return0;)測試:由于本題默認(rèn)所有的輸入都是合理的,所以我們不對輸入的數(shù)據(jù)是否位整數(shù)進(jìn)行檢查(盡管這是必要的,我們會(huì)在以后的實(shí)驗(yàn)提到如何實(shí)現(xiàn))。同時(shí),我們注意到本題的可能執(zhí)行情況在正常情況下只有一種(但為了使驗(yàn)證結(jié)果具有說服力,我們依然需要數(shù)組測試數(shù)據(jù)),且本題的測試數(shù)據(jù)相當(dāng)龐大(特別是將其轉(zhuǎn)化為二進(jìn)制后),所以我們需要借助計(jì)算機(jī)將其轉(zhuǎn)化為二進(jìn)制數(shù)并進(jìn)行相應(yīng)的人工轉(zhuǎn)化并驗(yàn)證。此外,本題的驗(yàn)證還有一個(gè)關(guān)鍵之處,即IP地址的輸出順序是否符合要求,具體測試數(shù)據(jù)見表1-3,運(yùn)行結(jié)果見圖1-9?1-11。表1-3編程題3的測試數(shù)據(jù)測試用例程序輸入理論結(jié)果運(yùn)行結(jié)果長整形形式二進(jìn)制(十進(jìn)制)用例14564561300000010⑵10111000(184)01111111(127)00101101(45)45.127.184.245.127.184.2用例212345678900000111(7)01011011(91)11001101(205)00010101(21)21.205.91.721.205.91.7用例378965432100101111(47)00010001(17)00101011(43)00110001(49)49.43.17.4749.43.17.47對應(yīng)測試測試用例1的運(yùn)行結(jié)果如圖1-9所示輸入長整數(shù)形式的iP地址:45645613這個(gè)ip姬址常規(guī)形式為:45.127.184.2圖1-9編程題3的測試用例一的運(yùn)行結(jié)果對應(yīng)測試測試用例2的運(yùn)行結(jié)果如圖1-10所示。黔球錯(cuò)勰拶巴;梵寬7圖1-10編程題3的測試用例二的運(yùn)行結(jié)果對應(yīng)測試測試用例3的運(yùn)行結(jié)果如圖1-11所示。麟球賽勰拜址■鱉舐7圖1-11編程題3的測試用例三的運(yùn)行結(jié)果說明上述的運(yùn)行結(jié)果與理論分析吻合,驗(yàn)證了程序的正確性。1.3自設(shè)題問題:仿照程序設(shè)計(jì)題3,設(shè)計(jì)一段程序,當(dāng)我們輸入一段IP地址(常規(guī)形式)時(shí),輸出其長整數(shù)形式的IP地址。解答:本題中由于需要輸入IP地址,而IP地址是由句點(diǎn)分隔的,所以我們需要對格式化輸入函數(shù)進(jìn)行相應(yīng)設(shè)置,使之能正常輸入IP地址(否則會(huì)造成輸入域混亂,導(dǎo)致不可預(yù)知的錯(cuò)誤),而當(dāng)我們按格式輸入了IP地址之后,我們只需要將程序設(shè)計(jì)題3的程序中的處理順序逆轉(zhuǎn)即可(由于我們可以先進(jìn)行按位與運(yùn)算,再進(jìn)行移動(dòng),所以我們可以只使用一個(gè)邏輯尺;此外,關(guān)于CPU處理數(shù)據(jù)順序的差異,可以在輸入時(shí)即交換順序,即用戶按實(shí)際順序輸入數(shù)據(jù),而程序按CPU處理順序接受數(shù)據(jù))。算法見流程圖1-4,其余細(xì)節(jié)見程序注釋,程序如下。#include<stdio.h>intmain(){unsignedlongip4,ip3,ip2,ipl,ip; 〃會(huì)發(fā)生移動(dòng),故其最大值并非128,不采用char型ip=0;〃使用前需按需初始化為0printf("請輸入常規(guī)形式的1P地址:");scanf^s("%lu.%lu.%lu.%lu",&ip4,&ip3,&ip2,&ipl);〃再輸入時(shí)即按CPU順序交換了存儲(chǔ)順序

unsignedlongm;m=OxOOOOOOfF;〃在移動(dòng)之前,僅有前8位需取出〃由于已經(jīng)發(fā)生移動(dòng),故此處無需交換順序ip+=(ipl&m)?24;〃由于已經(jīng)發(fā)生移動(dòng),故此處無需交換順序ip+=(ip2&m)?16;ip+=(ip3&m)?8;ip+=(ip4&m);printf("該IP地址的長整數(shù)形式為:%lu\n",ip);return0;流程圖1-4流程圖1-4自設(shè)題的算法測試:本題的測試只需將程序設(shè)計(jì)題中的測試數(shù)據(jù)輸入輸出逆轉(zhuǎn)即可(理論分析由于與程序設(shè)計(jì)題3完全相同,故略去),測試數(shù)據(jù)見表1-4,程序運(yùn)行結(jié)果見圖1-12,程序運(yùn)行結(jié)果與理論相符,驗(yàn)證了程序的正確性。表1-3編程題3的測試數(shù)據(jù)測試用例程序輸入理論結(jié)果運(yùn)行結(jié)果用例145.127.184.24564561345.127.184.2用例221.205.91.712345678921.205.91.7用例349.43.17.4778965432149.43.17.47理論分析由于與程序設(shè)計(jì)題3完全相同,故略去I測試用例1請輸入常規(guī)形式的IP地址:45.127.184.2該IP地址的長整數(shù)形式為:45645613測試用例2請輸入常規(guī)形式的IP地址:21.205.91.7該IP地址的長整數(shù)形式為:123456789測試用例3請輸入常規(guī)形式的IP地址:49.43.17.47該IP地址的長整數(shù)形式為:789654321圖1-12自設(shè)題程序的運(yùn)行結(jié)果1.4實(shí)驗(yàn)小結(jié)這是我第一次撰寫的實(shí)驗(yàn)報(bào)告,自然,會(huì)有很多的不完善之處,由于目前的知識(shí)有限,諸如流程控制,數(shù)組,編譯預(yù)處理等編程技術(shù)都無法使用,而這些技術(shù)的使用無疑會(huì)給本次實(shí)驗(yàn)程序的編制帶來極大的方便。誠然,不使用這些手段進(jìn)行編程的能力也是十分重要的,而本次實(shí)驗(yàn)恰好鍛煉了我們的此種能力,使我們使用簡單而基本的運(yùn)算與流程,去實(shí)現(xiàn)一些稍復(fù)雜的程序。而即使是這樣較為基本的編程實(shí)踐中,我也發(fā)現(xiàn)了很多自己平時(shí)并不注意的問題。比如在最開始我的部分返回值類型不為void的main函數(shù)卻沒有返回值,這使得我的程序在邏輯上并不完整(盡管運(yùn)行結(jié)果看上去是對的)。而除了在編程上的體會(huì)之外,我對實(shí)驗(yàn)報(bào)告的書寫也略有感觸。這是我第一次書寫實(shí)驗(yàn)報(bào)告,在書寫實(shí)驗(yàn)報(bào)告的過程中,我遇到了很多困難,比如流程圖的繪制和圖與表格的命名,但在指導(dǎo)老師與助教熱心幫助下,我逐一克服了這些困難,并在解決這些困難的同時(shí)使自己的能力也得到了相應(yīng)的提高。實(shí)驗(yàn)2流程控制實(shí)驗(yàn)2.1實(shí)驗(yàn)?zāi)康?1)掌握if-else,do-while,switch-case等流程控制語句之用法。(2)能正確理解各流程控制語句所包含的邏輯關(guān)系。(3)能正確理解各流程控制語句之間不同,并用這些不同優(yōu)化自己的程序。(4)能用流程控制語句編寫簡單的C語言程序。2.2實(shí)驗(yàn)內(nèi)容及要求2.2.1源程序改錯(cuò)下面是計(jì)算s=n!的源程序,在這個(gè)源程序中存在若干語法和邏輯錯(cuò)誤。要求在計(jì)算機(jī)上對這個(gè)例子程序進(jìn)行調(diào)試修改,使之能夠正確完成指定任務(wù)。例如,8!=40320#include<stdio.h>intmain(void)(inti,n,s=l;printf{nPleaseentern:n);scanfifM%dn,n);fdr(i=l,i<=n,i-H-)s=s*i;printff%d!=%dn,n,s);return0;II}解答:(1)錯(cuò)誤修改:1),scanf在輸入時(shí)應(yīng)指向單元地址而非單元名稱,正確形式為:scanf("%d",&n);2),fbr語句表達(dá)式1,2,3之間應(yīng)用;分隔,正確形式為:(2)錯(cuò)誤修改后運(yùn)行結(jié)果:見圖2-1(8的階乘確為40320)Pleaseentern:8Bt-40320圖2-1修改后的運(yùn)行結(jié)果2.2.2源程序修改替換(1)修改第1題,分別用while和do-while語句替換for語句。解答:在使用while語句時(shí),其與for語句的主要差異在于沒有一個(gè)專門的語句為i賦予初值,所以需要在進(jìn)入循環(huán)之前,為i賦予初值1。而在其他的地方,則與經(jīng)ibr語句的處理基本一致,替換后的程序如下所示:#include<stdio.h>intmain(void)(inti=l,n,s=l;//相較于for語句的關(guān)鍵printf("Pleaseentern:");scanfi("%d",&n);while(i<=n)(s=s*i;iH;)printf("%d!=%d",n,s);return0;}運(yùn)行結(jié)果見圖2-2(8的階乘確為40320)Pleaseentern:77!?5040圖2-2while結(jié)構(gòu)下的運(yùn)行結(jié)果在使用do-while語句時(shí),其與while語句的差異特別體現(xiàn)在無論n的值為何值,其都會(huì)進(jìn)行一次循環(huán),但值得注意的是,這一次額外的循環(huán)(發(fā)生于輸入n=0時(shí))在i的初值為1時(shí),并不會(huì)改變s的值,從而并不需要進(jìn)行額外的處理,調(diào)換循環(huán)體與條件的位置即可,替換后的程序如下所示:#include<stdio.h>intmain(void)inti=l,n,s=l;printf("Pleaseentern:");scanfi("%d",&n);do{s=s*i;i++;}while(i<=n);〃交換條件與循環(huán)體的位置printf("%d!=%d",n,s);return0;)運(yùn)行結(jié)果見圖2-3(6的階乘確為720)Pleaseentern:66?=720圖2?3do-while結(jié)構(gòu)的運(yùn)行結(jié)果(2)修改第1題,要求輸入改為“整數(shù)s”,輸出改為“滿足n!^s的最小整數(shù)nwo例如,輸入整數(shù)為40310,輸出結(jié)果為n=8。解答:這個(gè)問題,從本質(zhì)上來說,是要找到一個(gè)數(shù),使它的階乘的值大于等于所輸入的n的值,且要求這個(gè)數(shù)的值最小。階乘的實(shí)現(xiàn),可借助之前編寫的程序,并將它作為一個(gè)子函數(shù)進(jìn)行調(diào)用,使主函數(shù)更加簡明,數(shù)的尋找可借助簡明的while循環(huán)來實(shí)現(xiàn),程序如下所示,#include<stdio.h>intf(intp){intd=l;inti;fbr(i=l;i<=p;i-H-)d*=i;returnd;)intmain(void){inti,n=l,s=l,sl;print/'Pleaseenters:n);scanf(f,%dM,&sl);while(sl>s)〃比較n++;s=f(n);〃計(jì)算階乘}printf("n=%d\n",n);return0;運(yùn)行結(jié)果見圖2-4(40320=8!>40312>7!=5040)Pleaseenters:40312m=8圖2-4第2題程序的運(yùn)行結(jié)果2.2.3程序設(shè)計(jì)(1)假設(shè)工資稅金按以下方法計(jì)算:x<1000元,不收取稅金;1000Wx<2000,收取5%的稅金;20000x<3000,收取10%的稅金;30000x<4000,收取15%的稅金;4000<x<5000,收取20%的稅金;x>5000,收取25%的稅金。編寫一個(gè)程序,輸入工資金額,輸出應(yīng)收取稅金額度,要求分別用if語句和switch語句來實(shí)現(xiàn)解答:首先對輸入的x進(jìn)行判斷,判斷其是否是一個(gè)合理的工資數(shù)目,如果不合理(比如說是負(fù)數(shù)),就輸出提示輸入不合理的內(nèi)容。而如果其輸入合理,則通過對x值的判斷,決定其對應(yīng)的稅收方式,而后進(jìn)行計(jì)算。需要注意的是,在if-else結(jié)構(gòu)下,對x的區(qū)間劃分比較顯然,但由于switch語句只能選擇整數(shù),結(jié)合x的分段區(qū)間寬度均為1000,于是將x除以1000后再強(qiáng)制轉(zhuǎn)換類型為int在進(jìn)入各case進(jìn)行運(yùn)算,同樣重要的是,注意到switch語句的特點(diǎn),我們可以巧妙的利用其特性,簡化程序語句。其余細(xì)節(jié)見程序注釋,算法見流程圖2-1與2-2,程序如下。#include<stdio.h>intmain(void)doublex,tax;printf("請輸入您的工資金額:,scanf_s("%lf,&x);if(x<0)printf("您輸入了錯(cuò)誤的工資,請檢查您的輸入H");〃檢查輸入是否合理else(if(x<1000)tax=0;elseif(x<2000)tax=(x- 1000)*0.05;elseif(x<3000)tax=(x- 2000)*0.10+ 1000* 0.05;elseif(x<4000)tax=(x- 3000)*0.15+ 1000* (0.10 +0.05);elseif(x<5000)tax=(x- 4000)*0.20+ 1000* (0.05 +0.10+0.15);elsetax=(x-5000)*0.25+1000*(0.05+0.10+0.15+0.20);printf("(IFELSE方式)您須交稅:%.21f元\n",tax);tax=0;〃為利用switch語句的特點(diǎn),會(huì)進(jìn)行累加運(yùn)算,此處需將tax清零switch(((int)x)/1000)//對switch僅能選擇整數(shù)的處理(default:tax+=(x-5000)*0.25;x=5000;〃注意到switch的特點(diǎn)case4:tax+=(x-4000)*0.20;x=4000;case3:tax+=(x-3000)*0.15;x=3000;case2:tax+=(x-2000)*0.10;x=2000;case1:tax+=(x-1000)*0.05;x=1000;〃此處的x=1000并不是必要的case0:;}printf("(SWITCH方式)您須交稅:%.21f元5",tax);)return0;流程圖2-1見下一頁。流程圖2-1程序設(shè)計(jì)題1的算法(if-else結(jié)構(gòu))流程圖2-2見下一頁。流程圖2-2程序設(shè)計(jì)題1的算法(switch結(jié)構(gòu))測試:測試數(shù)據(jù):見表2-1,在選取測試數(shù)據(jù)時(shí),我們注意到,首先應(yīng)檢測程序能否正確判斷輸入的正確性,故我們輸入-1(負(fù)數(shù))與.(非數(shù)字)。其次,我們在各數(shù)據(jù)段中選取具有代表性且易于人工驗(yàn)算的數(shù)據(jù),因此,我們在此處在各工資段中選取了500,1500,2500,3500,4500,5500.同時(shí),選取邊界數(shù)據(jù)0,1000,2000,3000,4000,防止程序無法正常處理邊界值,圖2-5的運(yùn)行結(jié)果說明結(jié)果與理論分析吻合,驗(yàn)證了程序的正確性。

表2-1編程題1的測試數(shù)據(jù)測試用例1i療輸入您的1:保金額:1錯(cuò)識(shí)的測試用例1i療輸入您的1:保金額:1錯(cuò)識(shí)的I:俗.清依:令您的輸入道輸入您的I.貨金額:+您檢入rtrt設(shè)的?:資.謫檢化您的蛤入測試川例3晴瑜入您的I:洗金制I:O(IFELSE方式)您須交稅:0.00元(SWITCH方式)您須交幣兌:0.D。元測試川例4i卉蛤入您的工資金額:500(IFELSE方式)您須交:0.00元(SWITCH方式)您須交稅:0.00元測I試用例5入您的工資金額:1000(IFELSE方式)您須交稅:0.00元(SWITCH方式)您須交稅:0.00元測試用例6儲(chǔ)檢入您的I:資金額:1500(IFELSE方式)您須交稅:25.00元(SWITCH方式)您須交稅:25.00元測試川例7i.'i除入您的工資金額:2000(IFELSE方式)您須交稅:50.00元(SWITCH方式)您須交稅:50.00元測試用例8i行輸入您的工資金額:2500(IFELSE方式)您須交稅:100.00元(SWITCH方式)色;須「爻稅:10600元測試用例9療輸入您的1:資金額:3C00:IFELSE方式)您須交稅:150.00元(SWITCH方式)您須交稅:150.00元測試用例10療輸入您的1:資金額:3500:IFELSE方式)您須交稅:225.00元:SWITCH方式)您須交稅:225.00元測試用例11次輸入您的工費(fèi)金額:4C00:IFELSE方式)您須交稅:300.00元:SWITCH方式)您須交稅:300.00元測試用例12青輸入您的工資金額:4500:IFELSE方式;)您須交稅:400.00元:SWITCH方式)您須交稅:400.00元測試用例13青輸入您的工資金額:5C00:IFELSE方式)您須交稅:500.00元:SWITCH方式)您須交稅:500.00元?jiǎng)t試用例14音輸入您的工資金額:5500:IFELSE方式)您須交稅:625.00元:SWITCH方式)你須學(xué)稅:625.0071-測試用例.程序輸入.理論若果運(yùn)行結(jié)果用例1.??.提示幻誤.提示錯(cuò)誤.用例2.4-提示命誤.提示錯(cuò)誤.用例3.0.00元.0.00元.照例4.5co0.00元.0.00元.用例5.10000.00元.0.007C用例6.150025.0(元25.00元.H例7.20005().(M比50.00元.用例8.2500100.0)元.100.00元.用例9.3000150.05元150.00元.用例103500.225.0)元.225.00元“him114000300.0)元.300.00元.用例12.4500400.0)元.400.00元.用例1350)0.500.0)元.500.00元.用例1455*)0.625.0)元.625.00元.圖2-5編程題1的測試用例一的運(yùn)行結(jié)果(2)編寫一個(gè)程序,將輸入的一行字符復(fù)制到輸出,復(fù)制過程中將一個(gè)以上的空格字符用一個(gè)空格代替。解答:這與C語言處理注釋文字的方式相似,為此,我們定義兩個(gè)字符單元,分別用于收集當(dāng)前收集的字符與上一個(gè)收集的字符,當(dāng)這兩個(gè)單元都收集到空格字符時(shí),停止輸出收集到的字符,否則,正常輸出收集到的字符,這樣,便可以將一個(gè)以上的空格字符用一個(gè)空格代替。其余細(xì)節(jié)見程序注釋,算法見流程圖2-3,程序如下。#include<stdio.h>intmain()charc,d=0;//搜集當(dāng)前字符的c單元與前一字符的d單元,注意由于最開始“前一字符”不存在,需給d賦初值while((c=getchar())!=EOF)if(c!=")printf("%c",c);//非空格字符正常輸出if(c==")if(d!='')print<"%c",c);〃非連續(xù)空格字符正常輸出d=c;//記錄前一字符return0;流程圖2-3程序設(shè)計(jì)題2的算法測試:為了測試本程序應(yīng)對各個(gè)位置的空格的能力,作者在各處放置了數(shù)量不等的空格,特別是首尾兩處,其次,為了測試程序是否會(huì)錯(cuò)誤的少輸出字符,作者將所有的非空格字符均設(shè)為2個(gè)及以上。測試數(shù)據(jù):字符串(前有2個(gè)空格)1122233llaabb111...3311AAAA444+++///666 (后有2個(gè)空格)理論輸出結(jié)果:(前有1個(gè)空格)1122233llaabbxlll...3311AAAA444+++///666(后有1個(gè)空格)對應(yīng)測試測試用例的運(yùn)行結(jié)果如圖2-6所示。特別提示,為使程序效果顯目,用字母x代表空格。下面的運(yùn)行結(jié)果說明結(jié)果與理論分析吻合,驗(yàn)證了程序的正確性。xxll22233xllaabbxxlll...33xxxllAAAA444+++〃/666xxxll22233xllaabbxlll...33x1lAAAA444+++///666x圖2-6編程題2的測試用例的運(yùn)行結(jié)果(3)編寫一個(gè)程序,打印如下的楊輝三角形。1 /*第0行*/TOC\o"1-5"\h\z1 1 /*第 1行 */1 2 1 /*第 2行 */13 3 11 4 6 4 11 5 10 10 5 11 6 15 20 15 6 11 7 21 35 35 21 7 11 8 28 56 70 56 28 8 11 9 36 84 12612684 36 9 1每個(gè)數(shù)據(jù)值可以由組合C/計(jì)算(表示第i行第j列位置的值),而C/的計(jì)算如下:C,°=l (i=0,l,2,…)C/=C/-'*(i-j+l)/jG=0,l,2,3,...,i)說明:本程序中為了打印出金字塔效果,要注意空格的數(shù)目。一位數(shù)之間是3個(gè)空格,兩位數(shù)之間有2個(gè)空格,3位數(shù)之間只有一個(gè)空格,程序編制過程中要注意區(qū)分。解答:首先,定義一個(gè)函數(shù)用于生成組合數(shù),題目中提供了一種很好的組合數(shù)生成方式,它能避免在計(jì)算到17的階乘時(shí)就會(huì)造成int溢出的結(jié)果使計(jì)算結(jié)果異常,從而提供了計(jì)算范圍更大的組合數(shù)的可能,當(dāng)然,在本題中組合結(jié)果最大只能是999(否則會(huì)出現(xiàn)4位數(shù)而無法構(gòu)成金字塔)。而到了生成金字塔的環(huán)節(jié),我們可以將每一個(gè)數(shù)的單元視作一個(gè)長度為4的磚塊,這樣,我們可以得到一個(gè)顯然的結(jié)論:為了得到金字塔,從最下面一層開始,在其前方輸出2個(gè)空格,并且每向上一層,就再增加兩個(gè)空格。最后這個(gè)10層的金字塔,塔底有10個(gè)數(shù),但值得注意注意的是這是(a+b)9的展開式各項(xiàng)系數(shù)而非(a+b嚴(yán)的,程序如下。#include<stdio.h>intzh(inta,intb)〃聲明一個(gè)新的函數(shù),使程序更簡明(intj,i,r=l;if(a==0&&b==0)return1;〃處理c(0,0)的特殊情況for(i=1;i<=a;i++)r=(r*(b-i+l))/i;〃組合數(shù)算法returnr;)voidmain(){inti,j,n,k,p;n=9;〃十階金字塔對應(yīng)的是(a+b)9的展開式fbr(i=0;i<=n;i++)(fbr(k=2*(n-i);k>0;k-)putchar('');〃生成空格fbr(j=0;j<=i;j++)printf("%4d",zh(j,i));//輸出數(shù)據(jù),注意%4d的使用滿足了題目對空格數(shù)的要求putchar('\n');))測試:本題無需輸入,輸出如下圖。111TOC\o"1-5"\h\z12 113 3 11 4 6 4 11 5 10 10 5 11 6 15 20 15 6 11 7 21 35 35 21 7 11 8 28 56 70 56 28 8 19 36 84 126 126 84 36 9 1圖2-7編程題3的運(yùn)行結(jié)果(4)編寫一個(gè)程序,將用戶輸入的任意正整數(shù)逆轉(zhuǎn),例如,輸入1234,輸出432lo解答:由于本題明確指出所逆轉(zhuǎn)的對象是正整數(shù),從而首先需要對獲得的輸入進(jìn)行判定,以確定其是否是符合題目要求的輸入。再確定輸入合乎題目要求之后,利用同余除法的特性,求出輸入數(shù)據(jù)除以十的余數(shù)并將其輸出,而后將輸入的數(shù)字除以十,由于輸入是int型,從而除以十的結(jié)果等效于消除了最后一位數(shù)字,再求出新的數(shù)字除以10的余數(shù),如此循環(huán)下去,便可輸出被逆轉(zhuǎn)的整數(shù),考慮到循環(huán)的邏輯簡明,故采用while語句。其余細(xì)節(jié)見程序注釋,算法見流程圖2-4,程序如下。流程圖2-4程序設(shè)計(jì)題4的算法#include<stdio.h>intmain()intn,s;printf("請輸入一個(gè)正整數(shù),本程序會(huì)將其逆轉(zhuǎn):");scanf^s("%d",&n);if(n<=0)printf("本程序只接受正整數(shù)輸入,請檢查您的輸入)〃檢查輸入是否合理elsewhile(n)〃注意,此處只用于判斷循環(huán)是否結(jié)束,不用于判斷輸入是否合s=n%10;printf("%d",s);〃輸出最后一位數(shù)n=n/10;〃消除最后一位數(shù))putchar('\n');printf("\t此即為逆轉(zhuǎn)結(jié)果");return0;}測試:首先,是對函數(shù)基本功能的測試,即測試其能否正確逆轉(zhuǎn)正整數(shù),在此,我們選取一個(gè)正常的正整數(shù)O,接下來測試程序?qū)Ξ惓]斎氲姆磻?yīng)一個(gè)異常輸入0(非正整數(shù)),一個(gè)異常輸入“。”(非數(shù)字),其預(yù)期結(jié)果與實(shí)際結(jié)果見表2-2,運(yùn)行結(jié)果見圖2-8。表2-2編程題1的測試數(shù)據(jù)測試用例程序輸入理論結(jié)果運(yùn)行結(jié)果用例1OOO用例2提示錯(cuò)誤提示錯(cuò)誤用例30提示錯(cuò)誤提示錯(cuò)誤測試用例:1請輸入一個(gè)正整數(shù),本程序會(huì)將其逆轉(zhuǎn):測試結(jié)果:測試用例:2請輸入一個(gè)正整數(shù),本程序會(huì)將其逆轉(zhuǎn):。本程序只接受正整數(shù)輸入,i療檢畬您的輸入測試用例:3請輸入一個(gè)正整數(shù),本程序會(huì)將其逆轉(zhuǎn):0本程不只接受正整數(shù)輸入,請檢代您的輸入圖2-8編程題4的運(yùn)彳丁結(jié)果2.2.4選做題編寫一個(gè)程序,用牛頓迭代法求方程f(x)=3/_4/_5x+13=。滿足精度e=10-6的一個(gè)近似根,并在屏幕上輸出所求近似根。牛頓迭代法求方程近似根的迭代公式為:\x0=alx*+i=xk-f(xk)/f\xk)其中,/'(x)是函數(shù)f(x)的導(dǎo)函數(shù)。牛頓迭代法首先任意設(shè)定的一個(gè)實(shí)數(shù)。來作為近似根的迭代初值xo,然后用迭代公式計(jì)算下一個(gè)近似根XI。如此繼續(xù)迭代計(jì)算X2,X3,…,Xn,直到氏-%區(qū)精度e,此時(shí)值x。即為所求的近似根。解答:首先,為了計(jì)算Xk+I我們應(yīng)先計(jì)算f(Xk)與F(Xk)而對這兩個(gè)多項(xiàng)式的計(jì)算,我們可以采用秦九韶算法,這樣可以減少對計(jì)算機(jī)而言較復(fù)雜的的乘法運(yùn)算,雖然對單次計(jì)算而言,這樣的簡化效果并不明顯,但在多次的迭代計(jì)算中(本題中進(jìn)行了三十三次),這樣的簡化可大幅提高計(jì)算效率。而在解決了f(Xk)與f'(Xk)的值后,為了使程序更加簡潔,我們將這兩個(gè)式子定義為新的函數(shù),與此同時(shí),將迭代過程也定義為一個(gè)新的函數(shù)。最后在判斷Xk+1與Xk的接進(jìn)程度時(shí),考慮到最初Xk+1并未賦值,我們在此處采用至少循環(huán)一次的do-while結(jié)構(gòu)。其余細(xì)節(jié)見程序注釋,算法見流程圖2-5,程序如下。#include<stdio.h>#include<math.h>doublefifdoublex)(return(((3*x-4)*x-5)*x+13);〃秦九韶算法)doubledf(doublex){return((9*x-8)*x-5);〃秦九韶算法)doublen(doublex)return(x-f(x)/df(x));〃迭代}voidmain(){doublexk=l,xp=l;intk=0;doxk=xp;xp=n(xk);k++;〃統(tǒng)計(jì)計(jì)算次數(shù)while(fabs(xp-xk)>le-6);printf("方程的根:%lf\n計(jì)算次數(shù):%d\n",xk,k);流程圖2-5選做題的算法測試:本題無需輸入,輸出見圖2-9。本方程的根為(sqrt(21799)/(2*3A(7/2))-249l/1458)A(l/3)+61/(81*(sqrt(21799)/(2*3A(7/2))-2491/1458)A(l/3))+4/9=-l.548909593下面的運(yùn)行結(jié)果說明結(jié)果與理論分析吻合,驗(yàn)證了程序的正確性。方程的根:T.548910計(jì)算次數(shù):33圖2-9選做題的的運(yùn)行結(jié)果2.3自設(shè)題問題:判斷一個(gè)數(shù)是否是質(zhì)數(shù)。解答:為判斷一個(gè)數(shù)是否是質(zhì)數(shù),我們通常是把小于這個(gè)數(shù)的每一個(gè)數(shù)去除這個(gè)數(shù)直到除到它自身為止(稱為1方法),但是這樣的效率很低,且會(huì)進(jìn)行大量的重復(fù)計(jì)算,于是有人提出只需要除到這個(gè)數(shù)的一半(稱為2方法),但事實(shí)上這樣也會(huì)造成重復(fù)計(jì)算,經(jīng)過理論分析表明,只需要除到這個(gè)數(shù)的平方根即可(稱為3方法),當(dāng)然,存在其他更優(yōu)越的方法,如Solovay-Strassen算法和Miller-Rabin算法,但它們較復(fù)雜,也有針對特定環(huán)境的方法,例如把一定范圍內(nèi)的質(zhì)數(shù)先生成,在使用進(jìn)行大小比較即可,但這針對多次查詢比較有效。在此,我們將比較1方法,2方法與3方法計(jì)算所需要的時(shí)間。特別地,對于3方法而言,開根號(hào)無論是對于人還是對于計(jì)算機(jī)都是一項(xiàng)復(fù)雜的工作,為提高計(jì)算效率,我們采用一個(gè)等價(jià)描述,即0<加46=加2與〃。這樣把需要多次迭代的開方運(yùn)算變成了乘法運(yùn)算,能顯著提高計(jì)算效率。至于計(jì)時(shí)方面,C語言的time.h中提供了相應(yīng)的函數(shù),我們可直接調(diào)用用來計(jì)時(shí),注意到它的精度是毫秒級(jí)的,所以它的精度是足夠的,其余細(xì)節(jié)見程序注釋。算法(僅包含質(zhì)數(shù)判斷)見流程圖2-6,程序如下.流程圖2-6自設(shè)題的算法#include<stdio.h>#include<time.h>〃用于計(jì)時(shí)#include<math.h>intf(intk,intx);〃索引函數(shù)intfl(intx);intf2(intx);intf3(intx);//計(jì)算函數(shù)voidmain(void){intx;intk=O;〃計(jì)數(shù)器a:x=100;k++;while(x<le5)〃防止計(jì)算過度,限制最大數(shù)值為十萬(printf("測試方法:%d\n",k);x*=10;printf("現(xiàn)在尋找小于%d的質(zhì)數(shù)\n",x);clocktstart,end;//注意只記錄計(jì)算質(zhì)數(shù)的時(shí)間start=clock();printf("找到%d個(gè)質(zhì)數(shù)\n",f(k,x));end=clock();printff用時(shí)%.0僵秒\n————=\n",1000*((double)end-start)/(CLKTCK));〃顯示時(shí)間)if(k<3)gotoa;〃合理使用goto簡化程序}intf(intk,intx){if(k=1)returnfl(x);〃l方法if(k=2)returnf2(x);〃2方法if(k=3)returnf3(x);〃3方法)intfl(intx){inti,j,n=0,k=0;for(i=3;i<x;i++)〃注意2肯定是質(zhì)數(shù),1不是質(zhì)數(shù)也不是合數(shù)for(j=2;j<i;j++)(if(i%j=0)n++;//n:合數(shù)判斷器一旦n不為0輸入的數(shù)即不為質(zhì)數(shù)if(n){k++;n=0;break;//k:合數(shù)計(jì)數(shù)器return(x-k-2);〃總數(shù)減去合數(shù)數(shù)與1即是質(zhì)數(shù)數(shù)}intf2(intx){inti,j,n=0,k=0;for(i=3;i<x;i++)//注意2肯定是質(zhì)數(shù),1不是質(zhì)數(shù)也不是合數(shù){for。=2;j<=i/2;j++)〃注意到等號(hào)是必要的,否則會(huì)漏掉形如2P(p為質(zhì)數(shù))的合數(shù)(if(i%j=0)n++;//n:合數(shù)判斷器一旦n不為0輸入的數(shù)即不為質(zhì)數(shù)if(n){k++;n=0;break;//k:合數(shù)計(jì)數(shù)器return(x-k-2);〃總數(shù)減去合數(shù)數(shù)與1即是質(zhì)數(shù)數(shù)}intf3(intx){inti,j,n=0,k=0;fbr(i=3;i<x;i++)〃注意2肯定是質(zhì)數(shù),1不是質(zhì)數(shù)也不是合數(shù){for(j=2;j*j<=i;j++)〃注意到等號(hào)是必要的,否則會(huì)漏掉形如p人2(p為質(zhì)數(shù))的合數(shù)

if(i%j=0)n++;//n:合數(shù)判斷器一旦n不為0輸入的數(shù)即不為質(zhì)if(n)(k++;n=0;break;//k:合數(shù)計(jì)數(shù)器)))return(x-k-2);〃總數(shù)減去合數(shù)數(shù)與1即是質(zhì)數(shù)數(shù)測試:本題無需輸入,查閱資料可知:1000以內(nèi)的質(zhì)數(shù)有168個(gè);10000以內(nèi)的質(zhì)數(shù)有1229個(gè);100000以內(nèi)的質(zhì)數(shù)有9592個(gè);1000000以內(nèi)的質(zhì)數(shù)有78498個(gè)。結(jié)果見圖2-10,與理論數(shù)目相符,驗(yàn)證了程序的正確性。測試方法:1現(xiàn)在尋找小于1000的質(zhì)數(shù)找至U168個(gè)旗數(shù)測試方法:1現(xiàn)在尋找小于1000的質(zhì)數(shù)找至U168個(gè)旗數(shù)小時(shí)0宅秒測試方法:1現(xiàn)右尋找小于1OOOO的質(zhì)數(shù)找到1229個(gè)歷數(shù)用時(shí)25把秒測試方法:2現(xiàn)在尋找小于100000的質(zhì)數(shù)找到9592個(gè)質(zhì)數(shù)用時(shí)964毫秒測試方法:1現(xiàn)在J技小廠100000的旗數(shù)找到9592個(gè)項(xiàng)數(shù)用時(shí)1637,完秒測試方法:3現(xiàn)在尋找小于1000的質(zhì)數(shù)找到168個(gè)質(zhì)數(shù)用時(shí)1亳秒測試方法:2現(xiàn)在才找小于1000的歷數(shù)找到168個(gè)質(zhì)數(shù)用時(shí)0亳秒測試方法:3現(xiàn)在尋找小于10000的質(zhì)數(shù)找到1229個(gè)質(zhì)數(shù)用時(shí)1亳秒測試方法:2現(xiàn)在尋找小于10000的質(zhì)數(shù)找到1229個(gè)質(zhì)數(shù)用時(shí)13亳秒測試方法:3現(xiàn)在尋找小于100000的質(zhì)數(shù)找到9592個(gè)質(zhì)數(shù)用時(shí)27亳秒圖2-10自設(shè)題程序運(yùn)行結(jié)果由此可見,算法的優(yōu)化對程序的運(yùn)行效率是多么的重要,同樣的問題,使用不同的算法,其效率之差可能接近80倍。特別需要指出的是,方法1與方法2都無法正常的尋找小于一百萬的質(zhì)數(shù)總數(shù),而方法3處理這個(gè)問題僅需740毫秒(見圖2-11),充分體現(xiàn)其優(yōu)越性。測試方法:3現(xiàn)在尋找小于1000000的質(zhì)數(shù)找到78498個(gè)質(zhì)數(shù)用時(shí)740毫秒圖2-11方法3尋找小于一百萬的質(zhì)數(shù)總數(shù)2.4實(shí)驗(yàn)小結(jié)在本次實(shí)驗(yàn)中,我對各種流程控制語句的使用更加熟悉了,同時(shí)也對它們之間的差距與各自的優(yōu)劣有了更加深刻的認(rèn)識(shí),比如while語句適合用于簡單的循環(huán)邏輯;而其衍生語句do-while語句適合用于一定會(huì)有循環(huán)發(fā)生的情形(即至少會(huì)執(zhí)行一次循環(huán)體中的內(nèi)容,如牛頓法求方程的根);而更加復(fù)雜的for語句則適合用于某些更加復(fù)雜的情況,但這些語句在本質(zhì)上是一致的,即可使用某一語句實(shí)現(xiàn)這三種語句的所有功能(當(dāng)然這會(huì)帶來不便)。而另一類型的流程控制語句(帶有選擇色彩的)if-else語句與switch語句則分別適用于較少選擇支與較多的選擇支,不過switch語句與if-else語句的最重要區(qū)別并不在此;它們的關(guān)鍵區(qū)別在于switch語句可用于某些需要滿足某一條件后順序執(zhí)行之后所有語句的情形。此外,在本次實(shí)驗(yàn)中,我也體會(huì)到了一個(gè)優(yōu)良的算法對程序執(zhí)行效率提高的重大作用,如在選做題中我們使用了秦九韶算法提高了多項(xiàng)式求值的效率;而在自設(shè)題的質(zhì)數(shù)判斷中,一個(gè)合適的條件(算法)對程序效率的提升那更是不言而喻的。實(shí)驗(yàn)3函數(shù)與程序結(jié)構(gòu)實(shí)驗(yàn)3.1實(shí)驗(yàn)?zāi)康?1)熟悉和掌握函數(shù)的定義、聲明;函數(shù)調(diào)用與參數(shù)傳遞方法;以及函數(shù)返回值類型的定義和返回值使用。(2)熟悉和掌握不同存儲(chǔ)類型變量的使用。(3)熟悉多文件編譯技術(shù)。3.2實(shí)驗(yàn)內(nèi)容及要求3.2.1源程序改錯(cuò)下面是計(jì)算s=l!+2!+3!+…+n!的源程序,在這個(gè)源程序中存在若干語法和邏輯錯(cuò)誤。要求在計(jì)算機(jī)上對這個(gè)例子程序進(jìn)行調(diào)試修改,使之能夠正確完成指定任務(wù)。#include<stdio.h>intmain(void){intk;fbr(k=l;k<6;k-H-)printf(nk=%d\tthesumis%ld\nn,k,sum_fac(k));return0;)longsum_fac(intn){longs=0;inti;longfac;fbr(i=l;i<=n;i-H-)fac*=i;s+=fac;returns;)解答:(1)錯(cuò)誤修改:1)第5行處的循環(huán)使得程序只能計(jì)算一些固定數(shù)的階乘和,正確形式為:scanf_s("%d",&k);2)第6行處使用了一個(gè)新定義的函數(shù)sum_fac(),但沒有預(yù)先聲明,正確形式為:(在第1行與第2行之間插入)longsum_fac(intn);3)第15行處使用了一個(gè)未初始化的變量fac,正確形式為:longfac=1;4)第15行與16行的計(jì)算邏輯有誤,這樣只能得到n!的值,正確形式為:{fac*=i;s+=fac;}(2)錯(cuò)誤修改后運(yùn)行結(jié)果:見圖3-1(1!+2!+3!=1+2+6=9)pleasethenunbei*k

k=3thesunis'圖3-1修改后的運(yùn)行結(jié)果3.2.2源程序修改替換(1)修改第1題中sumfac函數(shù),使其計(jì)算量最小。解答:第1題中sum_fac函數(shù)計(jì)算量較大主要是由于無論是在求階乘時(shí)還是在求其和時(shí)均出現(xiàn)了大量的重復(fù)運(yùn)算,為此,我們使用遞歸函數(shù)來減少計(jì)算量為此我們采用了靜態(tài)變量,注意這樣會(huì)使用“虛擬”(即計(jì)算但不輸出)的循環(huán)來達(dá)到記錄之前的階乘值得目的來簡化運(yùn)算,其余細(xì)節(jié)見程序注釋,程序如下。#include<stdio.h>longsum_fac(intn);intmain(void)(intk,i;printf("pleasethenumberk:");scan匚s("%d",&k);if(k<=0)printf("legalinput!");〃排除非法輸入else{for(i=l;i<=k;i++)if(i=k)printf("k=%d\tthesumis%ld\n",i,sum_fac⑴);〃注意longint的占位符elsesumfac(i);〃“虛擬”輸出))return0;)〃以下得函數(shù)使用靜態(tài)變量簡化了運(yùn)算staticlongfac=1,sum=0;longsum_fac(intn)(fac*=n;sum+=fac;returnsum;)運(yùn)行結(jié)果見圖3-2 (l!+2!+3!+4!=l+2+6+24=33)pleasethenunherk:4

k=4thesunis33圖3-2修改后的正常運(yùn)行結(jié)果pleasethenunbei*legalinput!圖3-3修改后的異常運(yùn)行結(jié)果(2)修改第1題中sumfhc函數(shù),計(jì)算s=1+,+'+...+2!3! 〃!解答:此處只需要每次計(jì)算階乘時(shí)改為計(jì)算其倒數(shù)即可,但特別需要注意的是,計(jì)算過程中會(huì)出現(xiàn)小數(shù),因此需要改變大部分變量的數(shù)據(jù)類型,其余細(xì)節(jié)見程序注釋,程序如下。#include<stdio.h>doublesum_fiac(intn);longfac(intn);〃注意數(shù)據(jù)類型的改變intmain(void){intk;printf("pleasethenumberk:");if(k<=0)printf("legalinput!");〃排除非法輸入scanf("%d",&k);printf(,,k=%d\tthesumis%lf\nn,k,sumfac(k));return0;)doublesum_fac(intn){if(n>1)return1.0/fac(n)+sum_fec(n-1);〃注意1,0的使用強(qiáng)制轉(zhuǎn)換了類型elsereturn1;}longfac(intn){if(n>1)returnn*fac(n-1);elsereturn1;)運(yùn)行結(jié)果見圖3-4與圖3-5-(1+1/2!=1+0,5=1.5)pleasetienumberk:2k?2thesunis1.500000圖3-4第2題程序的正常運(yùn)行結(jié)果pleasethenumbei*k:-1legalinput!圖3?5第2題程序的異常運(yùn)行結(jié)果3.2.3跟蹤調(diào)試題下面是計(jì)算fabonacci數(shù)列前n項(xiàng)和的程序,要求單步執(zhí)行程序,觀察p,i,sum,n值。#include<stdio.h>intmain(void)(inti,k;longsum=0,*p=∑/*聲明p為長整型指針,指向sum*/scanf(n%dn,&k);for(i=l;i<=k;i++){sum+=fiabonacci(i);printf(Mi=%d\tthesumis%ld\nM,i,*p);/**p等價(jià)于sum*/return0;longfabonacci(intn)(if(n==l||n==2)return1;elsereturnfabonacci(n-1)+fabonacci(n-2);)(以下第1?3題的分析以輸入的n=2為分析基礎(chǔ))(1)剛執(zhí)行完scanf("%d",&k);語句,p,i值是多少?、答:通過理論分析,由于p被設(shè)定為指向sum的指針,故其值與此時(shí)sum之值相同,而sum在聲明時(shí)已經(jīng)被賦予初值0,從而此時(shí)p的值也應(yīng)為0。而i此時(shí)僅被聲明而尚未被初始化,從而其值為一個(gè)在int范圍內(nèi)的隨機(jī)數(shù)。跟蹤的實(shí)際結(jié)果圖3-6所示,與理論分析相符。0*p0 lone*i-858993460 int圖3-6步驟(1)的跟蹤結(jié)果(2)從fabonacci函數(shù)返回后光條停留在哪個(gè)語句上?答:通過理論分析,由于是從第8行進(jìn)入fabonacci函數(shù)且在進(jìn)入前第8行的計(jì)算尚未完全結(jié)束,所以從fabonacci函數(shù)返回后應(yīng)繼續(xù)未完成的計(jì)算,即光標(biāo)應(yīng)停在第8行。跟蹤的實(shí)際結(jié)果圖3-7所示,與理論分析相符。? 8 sum+=fabonacci(i);已用時(shí)間<=ims圖3-7步驟(2)的跟蹤結(jié)果(3)進(jìn)入Fibonacci函數(shù),watch窗口顯示的是什么?答:通過理論分析,在第一次進(jìn)入fabonacci函數(shù)時(shí),watch窗口中應(yīng)顯示帶入的參數(shù),又此時(shí)僅帶入了參數(shù)i,而參數(shù)i的值又為1,從而該窗□應(yīng)顯示n=l。而在第二次進(jìn)入時(shí),i=2,同理該窗口應(yīng)顯示n=2。跟蹤的實(shí)際結(jié)果圖3-8與圖3-9所示,與理論分析相符。

自礴口名稱直?nI▼9x類型int自助窗口▼9x類型int圖3-8步驟(3)的跟蹤結(jié)果(第一次進(jìn)入)自動(dòng)窗口 7x名稱 直 類型。n2 int自動(dòng)窗口局部變量監(jiān)視1圖3-9步驟(3)的跟蹤結(jié)果(第二次進(jìn)入)(4)當(dāng)i=3,從調(diào)用fabonacci函數(shù)到返回,n值如何變化?答:通過理論分析,在第一次進(jìn)入fabonacci函數(shù)時(shí),watch窗口中應(yīng)顯示帶入的參數(shù),又此時(shí)僅帶入了參數(shù)i,而參數(shù)i的值又為3,從而該窗□應(yīng)顯示n=3,此時(shí)n不是1或2中的任意一個(gè),故進(jìn)入else后的語句,該語句中參數(shù)分別為2與1,從而該窗口應(yīng)顯示n=2與n=l,之后,會(huì)直接進(jìn)入if后的語句,該語句不會(huì)再為fabonacci函數(shù)提供參數(shù),所以不再進(jìn)入fabonacci函數(shù),當(dāng)然,在完成這些計(jì)算后,在return之前,n的值又一次變回3,從而該窗口應(yīng)顯示n=3,此后,n便不復(fù)存在。跟蹤的實(shí)際結(jié)果圖3-10至圖3-14所示,與理論分析相符。自動(dòng)窗口 7X名稱 值 類型?n2 int自動(dòng)窗口局部變量監(jiān)視1圖3-10步驟(4)的跟蹤結(jié)果(剛進(jìn)入)

110%Elongfabonacci(intn)110%{已用時(shí)間<=1msif(n==111n?

return1;returnfabonacelsereturnfabonac自動(dòng)直口局部變量監(jiān)視1圖3-11步驟(4)的跟蹤結(jié)果(計(jì)算自bonacci(2))在動(dòng)窗口 ▼qx名稱值 類型。n1 int自動(dòng)窗口局部變量監(jiān)視1圖3-12步驟(4)的跟蹤結(jié)果(計(jì)算fabonacci(l))自麗口 ▼Qx名梆值 類型名梆值 類型自初窗口曷部變量監(jiān)視1圖3-13步驟(4)的跟蹤結(jié)果(return后)自動(dòng)窗口TOC\o"1-5"\h\z名梆 值0*p 4?i 4.sum 4圖3?14步驟(4)的跟蹤結(jié)果(退出后)3.2.4程序設(shè)計(jì)題(1)編程讓用戶輸入兩個(gè)整數(shù),計(jì)算兩個(gè)數(shù)的最大公約數(shù)并且輸出之(要求用遞歸函數(shù)實(shí)現(xiàn)求最大公約數(shù))。同時(shí)以單步方式執(zhí)行該程序,觀察遞歸過程。解答:首先,為了使計(jì)算盡量簡單,我們使用輾轉(zhuǎn)相減法來計(jì)算最大公約數(shù),同時(shí),輾轉(zhuǎn)相減法也是用于單步觀察執(zhí)行過程的優(yōu)良算法(因其計(jì)算結(jié)果簡單且計(jì)算次數(shù)較少)并且也可使用遞歸來提高運(yùn)算效率,其余細(xì)節(jié)見程序注釋,算法見流程圖3-1,程序如下。流程圖3-1程序設(shè)計(jì)題(1)的算法#include<stdio.h>intR);voidmain()inta,b;prin氓"請輸入兩個(gè)正整數(shù)(以空格分隔):");scan7%d%d",&a,&b);if(a<=0||b<=0)printf("您輸入了非正整數(shù)內(nèi)容,請檢查您的輸入\n");//檢查非法輸入elseprint口"它們的最大公約數(shù)是:%d\n",f(a,b));intf(inta,intb)//輾轉(zhuǎn)相減法

if(a=b)returna;if(a>b)returnf(a-b,b);if(a<b)returnf(a,b-a);測試:首先,我們應(yīng)測試程序能否正常運(yùn)行,為此我們選擇了具有多個(gè)公因數(shù)(非1)的90與60,而后選擇具有倍數(shù)關(guān)系的5與10與相等兩數(shù)12與12(注意到其擁有多個(gè)因數(shù)),接著又提供了一組帶有1的測試樣例7與1,以測試在非常情況下程序的

溫馨提示

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

評(píng)論

0/150

提交評(píng)論