




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第九講: C語言高級編程(第三部分) (習(xí)題課及動態(tài)數(shù)組),北京大學(xué) 信息科學(xué)技術(shù)學(xué)院 2009年12月,上機(jī)過程中的問題,養(yǎng)成良好的程序書寫風(fēng)格 變量、函數(shù)的命名:體現(xiàn)其意義 if/else、swith/case、for、while等復(fù)合語句中 的使用 內(nèi)代碼的縮進(jìn) 適當(dāng)?shù)目招?適當(dāng)?shù)淖⑨?避免太長的語句、適當(dāng)?shù)膿Q行,上機(jī)過程中的問題,應(yīng)該: 仔細(xì)分析問題 考慮各種情況 把自己當(dāng)作計算機(jī),給定輸入,再運行一下程序 誤解: 在VC環(huán)境中寫完程序后,就拷貝到編程網(wǎng)格上提交 在VC環(huán)境中編譯正確,程序就是正確的 對于給出的樣例輸入,輸出正確,程序就是正確的,程序運行不正確,怎么辦?,程序的調(diào)試,語
2、法錯誤:編譯(組建)錯誤 不要驚慌,編譯結(jié)果輸出窗口已經(jīng)為你指明了程序的出錯行及錯誤原因,可以據(jù)此來修改程序錯誤。 改錯時,應(yīng)從出錯信息中的第一條開始,用鼠標(biāo)雙擊該條信息,程序源文件窗口就將定位到出錯行。 很多時候,程序編譯后會出很多錯誤,但很可能是由第一個錯誤衍生而來的,改完第一個錯誤后,再編譯時其他錯誤就不再出現(xiàn)了。所以,應(yīng)該每修改完一個錯誤后就編譯一次。,二、關(guān)于程序的錯誤修改及調(diào)試,這里少了一個“”。,雙擊第一行,定位錯誤及了解錯誤原因!,程序的調(diào)試,運行結(jié)果錯:程序跟蹤調(diào)試 由于程序算法及其他原因,執(zhí)行結(jié)果不正確,這時從源程序表面上就很難發(fā)現(xiàn)錯誤。 跟蹤調(diào)試:可以手動一步一步執(zhí)行程序
3、語句,在每條語句執(zhí)行后,可以查看相關(guān)變量的值,以判斷和預(yù)期結(jié)果是否相符;也可以了解程序的執(zhí)行順序,看它是否和預(yù)期的程序流程相符。 斷點設(shè)定:在跟蹤調(diào)試前,還需要確定一下程序可能從哪里出錯,設(shè)置一個斷點,讓程序在此停止自動運行,由我們手動一步一步發(fā)出程序執(zhí)行命令。如果不能確定程序是從哪里出錯,則可以將斷點設(shè)置在程序的第一條語句處。,設(shè)置程序斷點,跟蹤方式執(zhí)行程序,查看變量值,當(dāng)前程序執(zhí)行停留在此行,程序手動執(zhí)行 進(jìn)入函數(shù) 一步一步執(zhí)行 從函數(shù)中執(zhí)行出來 執(zhí)行到光標(biāo)所在行,手動設(shè)置變量,查看變量值,問題1:學(xué)生、課程的平均成績,使用一維數(shù)組,問題描述,某個年級有180名學(xué)生; 在某一個學(xué)期,這個年
4、級開了8門必修課; 期末考試結(jié)束后,每個學(xué)生每門課程的成績出來了; 教務(wù)老師 請我們編寫一段程序: 計算每個學(xué)生的平均成績; 計算每門課程的平均成績。,每個學(xué)生 的 平均成績,每門課程 的 平均成績,每個學(xué)生 的 總成績,每門課程 的 總成績,每個學(xué)生 每門課程 的 成績,如何 把這些數(shù)據(jù)存放在變量中?,使用數(shù)組,每個學(xué)生 的 平均成績,每門課程 的 平均成績,每個學(xué)生 的 總成績,每門課程 的 總成績,每個學(xué)生 每門課程 的 成績,double cj1808,double zcj_xs180,double zcj_kc8,double pjcj_xs180,double pjcj_kc8,S
5、tep 0: 定義 存放數(shù)據(jù) 的 數(shù)組,Step 1: 輸入 每個學(xué)生 每門課程 的 成績,Step 2: 計算 每個學(xué)生 的 總成績,Step 4: 計算 每個學(xué)生 的 平均成績,Step 3: 計算 每門課程 的 總成績,Step 5: 計算 每門課程 的 平均成績,Step 6: 輸出 每個學(xué)生 的 平均成績,Step 7: 輸出 每門課程 的 平均成績,Step 0: 定義 存放數(shù)據(jù) 的 數(shù)組,#define XSSL 180 #define KCSL 8 #include int main() double cjXSSLKCSL; double zcj_xsXSSL, pjcj_xs
6、XSSL; double zcj_kcKCSL, pjcj_kcKCSL; return 0; ,cj1808,zcj_kc8,pjcj_kc8,zcj_xs180,pjcj_xs180,Step 0: 定義 存放數(shù)據(jù) 的 數(shù)組,Step 1: 輸入 每個學(xué)生 每門課程 的 成績,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) scanf(“%lf”, ,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_xsx += cjxk; ,Step 2: 計算 每個學(xué)生 的 總
7、成績,沒有 對數(shù)組zcj_xs初始化,for(int x = 0; x XSSL; x+) zcj_xsx = 0; for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_xsx += cjxk; ,Step 2: 計算 每個學(xué)生 的 總成績,Step 3: 計算 每門課程 的 總成績,for(int k = 0; k KCSL; k+) zcj_kck = 0; for(int k = 0; k KCSL; k+) for(int x = 0; x XSSL; x+) zcj_kck += cjxk; ,for(int x = 0
8、; x XSSL; x+) pjcj_xsx = zcj_xsx/KCSL; ,Step 4: 計算 每個學(xué)生 的 平均成績,for(int k = 0; k KCSL; k+) pjcj_kck = zcj_kck/XSSL; ,Step 5: 計算 每門課程 的 平均成績,Step 6: 輸出 每個學(xué)生 的 平均成績,Step 7: 輸出 每門課程 的 平均成績,for(int k = 0; k KCSL; k+) printf(“Course %d: %.1lfn”, k, pjcj_kck); ,for(int x = 0; x XSSL; x+) printf(“Student %d
9、: %.1lfn”, x, pjcj_xsx); ,int main() double cjXSSLKCSL; /step0: 定義存放數(shù)據(jù)的數(shù)組 double zcj_xsXSSL, pjcj_xsXSSL; double zcj_kcKCSL, pjcj_kcKCSL; for(int x = 0; x XSSL; x+) /Step 1: 輸入 每個學(xué)生 每門課程 的 成績 for(int k = 0; k KCSL; k+) scanf(“%lf”, ,for(int k = 0; k KCSL; k+)/Step 3: 計算 每門課程 的 總成績 zcj_kck = 0; for(i
10、nt k = 0; k KCSL; k+) for(int x = 0; x XSSL; x+) zcj_kck += cjxk; for(int x = 0; x XSSL; x+)/Step 4: 計算 每個學(xué)生 的 平均成績 pjcj_xsx = zcj_xsx/KCSL; for(int k = 0; k KCSL; k+)/Step 5: 計算 每門課程 的 平均成績 pjcj_kck = zcj_kck/XSSL; for(int x = 0; x XSSL; x+)/Step 6: 輸出 每個學(xué)生 的 平均成績 printf(“Student %d: %.1lfn”, x, pj
11、cj_xsx); for(int k = 0; k KCSL; k+)/Step 7: 輸出 每門課程 的 平均成績 printf(“Course %d: %.1lfn”, k, pjcj_kck); return 0; ,如果不能使用二維數(shù)組, 這個問題該如何求解?,Step 0: 定義 存放數(shù)據(jù) 的 數(shù)組,#define XSSL 180 #define KCSL 8 #include int main() double cjXSSLKCSL; double zcj_xsXSSL, pjcj_xsXSSL; double zcj_kcKCSL, pjcj_kcKCSL; return 0;
12、 ,#define XSSL 180 #define KCSL 8 #include int main() double cjXSSLKCSL; double zcj_xsXSSL, pjcj_xsXSSL; double zcj_kcKCSL, pjcj_kcKCSL; for(int x = 0; x XSSL; x+) zcj_xsx = 0; for(int k = 0; k KCSL; k+) zcj_kck = 0; return 0; ,Step 3: 計算 每門課程 的 總成績,for(int k = 0; k KCSL; k+) for(int x = 0; x XSSL;
13、x+) zcj_kck += cjxk; ,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_kck += cjxk; ,Step 3: 計算 每門課程 的 總成績,for(int k = 0; k KCSL; k+) for(int x = 0; x XSSL; x+) zcj_kck += cjxk; ,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_kck += cjxk; ,1 2 3 4 5,1 2 3 4 5,Step 2: 計算 每個學(xué)生 的 總成
14、績,Step 3: 計算 每門課程 的 總成績,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_xsx += cjxk; ,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_kck += cjxk; ,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_xsx += cjxk; zcj_kck += cjxk; ,Step 2: 計算 每個學(xué)生 的 總成績 Step 3: 計算 每門課程 的 總成績
15、,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) zcj_xsx += cjxk; zcj_kck += cjxk; ,Step 1: 輸入 每個學(xué)生 每門課程 的 成績,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) scanf(“%lf”, ,for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) scanf(“%lf”, , double cj; for(int x = 0; x XSSL; x+) for(int k
16、 = 0; k KCSL; k+) scanf(“%lf”, ,Step 1: 輸入 每個學(xué)生 每門課程 的 成績 Step 2: 計算 每個學(xué)生 的 總成績 Step 3: 計算 每門課程 的 總成績, double cjXSSLKCSL; for(int x = 0; x XSSL; x+) for(int k = 0; k KCSL; k+) scanf(“%lf”, ,for(int x = 0; x XSSL; x+) pjcj_xsx = zcj_xsx/KCSL; ,for(int k = 0; k KCSL; k+) pjcj_kck = zcj_kck/XSSL; ,for(
17、int k = 0; k KCSL; k+) printf(“Course %d: %.1lfn”, k, pjcj_kck); ,for(int x = 0; x XSSL; x+) printf(“Student %d: %.1lfn”, x, pjcj_xsx); ,這四段代碼 是否也能優(yōu)化優(yōu)化?,請課后思考,4,5,6,7,問題2:輸入兩個日期(年 月 日),求兩個日期之間相隔的天數(shù),輸入,輸出,輸入輸出示例,1978 10 1 1978 10 1,0,1978 10 1 1978 10 2,1,1978 10 2 1978 10 1,1,2001 1 1 2000 1 1,366,2
18、000 1 1 2002 1 1,731,注意:1. 輸入的日期沒有固定的次序關(guān)系; 2. 兩個日期不一定是在同一年; 3. 必須考慮閏年的因素,可以利用的三個函數(shù),判斷閏年的函數(shù) int isRunNian(int year) 求解某一日期是當(dāng)年的第幾天的函數(shù) int DiJiTian(int year, int month, int day) 交換兩個變量的值的函數(shù) void swap(int *a, int *b),判斷閏年的函數(shù),int isRunNian(int year) int result; if(year%400 = 0 |(year%4=0 ,求解某一日期是當(dāng)年的第幾天的函
19、數(shù),int DiJiTian(int year, int month, int day) int result = 0; for(int i = 1; i month; i+) /step1 if(i=1|i=3|i=5|i=7|i=8|i=10|i=12) result += 31; else if (i = 4 | i =6 | i = 9 | i=11) result += 30; else if(i = 2) if(isRunNian(year) result += 29; else result += 28; result += day;/step2 return result; ,
20、void swap(int *a, int *b) int e; e = *a; *a = *b; *b = e; ,交換兩個變量的值的函數(shù),準(zhǔn)備工作,#include int DiJiTian(int year, int month, int day); int isRunNian(int year); void swap(int *a, int *b); int main() int year1, month1, day1; int year2, month2, day2; int result = 0; scanf(%d %d %d, ,在此處插入你的代碼,問題分析,這兩種情況 有什么區(qū)
21、別?,問題分析,分兩種情況考慮: 情況1: 當(dāng)兩個日期 在 同一年; 情況2: 當(dāng)兩個日期 不在 同一年;,#include int DiJiTian(int year, int month, int day); int isRunNian(int year); void swap(int *a, int *b); int main() int year1, month1, day1; int year2, month2, day2; int result = 0; scanf(%d %d %d, ,情況1:當(dāng)兩個日期 在 同一年,result,a,b,情況1:當(dāng)兩個日期 在 同一年,/情況1
22、的代碼 result = DiJiTian(year1, month1, day1) - DiJiTian(year2, month2, day2); if(result 0) result = 0 - result; ,請一位同學(xué) 在黑板上寫下: 情況1對應(yīng)的代碼,情況2:當(dāng)兩個日期 不在 同一年,result,a,b,c,result = a + b + c,情況2:當(dāng)兩個日期 不在 同一年,/情況2的代碼 if(year1 year2) swap( ,int a, b, c; /計算a的代碼 /計算b的代碼 /計算c的代碼 result = a + b + c;,情況2:當(dāng)兩個日期 不在
23、 同一年,/計算a的代碼,if(isRunNian(year1) a = 366 - DiJiTian(year1, month1, day1); else a = 365 - DiJiTian(year1, month1, day1); ,情況2:當(dāng)兩個日期 不在 同一年,/計算b的代碼,b = 0; for(int i = year1 + 1; i year2; i+) if(isRunNian(i) b += 366; else b += 365; ,情況2:當(dāng)兩個日期 不在 同一年,/計算c的代碼,c = DiJiTian(year2, month2, day2);,問題3:騎車與走路
24、,騎車: 找到并啟動自行車 27秒; 停車鎖車 23秒; 速度 3.0米秒;,走路: 速度 1.2米秒;,假設(shè) n 的上限是 10,#include #define N 10 void compute(int distance); int main() int n; int distanceN; int i; scanf(%d, ,void compute(int distance) int timeBike = 27 + 23 + distance/3; int timeWalk = (int)(distance/1.2); if(timeBike timeWalk) printf(Walk
25、n); else printf(Alln); ,提交到 編程網(wǎng)格。結(jié)果是 ,把 n 的上限修改為 100,#include #define N 100 void compute(int distance); int main() int n; int distanceN; int i; scanf(%d, ,void compute(int distance) int timeBike = 27 + 23 + distance/3; int timeWalk = (int)(distance/1.2); if(timeBike timeWalk) printf(Walkn); else pri
26、ntf(Alln); ,提交到 編程網(wǎng)格。結(jié)果是 ,WHY?,編程網(wǎng)格 判斷程序是否正確 的機(jī)制,對每一個題目, 編程網(wǎng)格 預(yù)先設(shè)定了 一組測試數(shù)據(jù);,只要你的程序在這組測試數(shù)據(jù)下正確, 編程網(wǎng)格 即認(rèn)為 你的程序是正確的;,在 騎車與走路 這個題目中, 編程網(wǎng)格使用的測試數(shù)據(jù)中,所有的n 都小于 100,有沒有更穩(wěn)妥的辦法呢?,動 態(tài) 數(shù) 組,靜態(tài)數(shù)組,int sz10;,必須是一個常量,靜態(tài)數(shù)組 的 長度 在 編譯時刻 就確定了;,如何能在程序的運行時刻, 動態(tài)地確定一個數(shù)組的長度呢?,動態(tài)數(shù)組,include int main() int n; scanf(“%d”, ,在VC下編譯失敗
27、!,error C2133: shuzu : unknown size,怎樣才能實現(xiàn) 動態(tài)數(shù)組?,動態(tài)數(shù)組,如何實現(xiàn)動態(tài)數(shù)組? 1、使用指針 2、自己申請內(nèi)存,動態(tài)數(shù)組,include int main() int n; scanf(“%d”, ,include include int main() int n; scanf(“%d”, ,動態(tài)數(shù)組,include int main() int n; scanf(“%d”, ,include include int main() int n; scanf(“%d”, ,關(guān)于malloc()/free()的使用,別忘了: #include mal
28、loc函數(shù)的參數(shù)為所需申請內(nèi)存的大?。阂宰止?jié)為單位 malloc函數(shù)返回一個void*類型的地址,必須通過強(qiáng)制類型轉(zhuǎn)換,才能賦值給特定的指針變量: int * pint = (int *) malloc( . ); 用malloc函數(shù)生成各種類型的動態(tài)數(shù)組,最好使用“sizeof(類型名) * 動態(tài)數(shù)組長度”形式確定分配內(nèi)存的大?。?int * pint = (int *) malloc( sizeof(int) * 100 ); 分配的內(nèi)存不再使用時一定要釋放: free(pint);,動態(tài)數(shù)組,malloc()在內(nèi)存中分配的一塊連續(xù)的內(nèi)存區(qū)域,這與靜態(tài)數(shù)組在內(nèi)存中的布局是一樣的。因此,指向這塊內(nèi)存區(qū)域的指針變量就可以像數(shù)組一樣使用了: int *pint; pint = (int *)malloc(sizeo(int)*10); pint0, pint1, , pint9 在使用動態(tài)數(shù)組時,一定要注意不要越界引用,即不要引用并沒有分配給你使用的內(nèi)存: 當(dāng)引用pint10 時,對于C語言來說,這是合法的,但是它所引用的卻是所分配的內(nèi)存區(qū)域之外的其他內(nèi)存區(qū)域,其內(nèi)的值是未知的;如果對其進(jìn)
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 認(rèn)知能力發(fā)展教育
- 高中開學(xué)安全教育指南
- 甲狀腺切口引流管的護(hù)理
- 《智能網(wǎng)聯(lián)整車綜合測試》課件-超車場景測試評價
- 《社會財務(wù)共享服務(wù)實務(wù)》課件-個人所得稅申報
- 預(yù)防流感安全課件
- 預(yù)應(yīng)力混凝土工程課件
- 船員上船前培訓(xùn)指南
- 韻母un的課件教學(xué)課件
- 音樂鑒賞課件作品介紹
- 《樹立正確的“三觀”》班會課件
- 園林綠化移樹合同
- 醫(yī)療機(jī)構(gòu)保潔人員培訓(xùn)
- 企業(yè)員工健康促進(jìn)計劃的設(shè)計與實施
- 助理工程師答辯演示
- 成人失禁相關(guān)性皮炎的預(yù)防與護(hù)理-護(hù)理團(tuán)標(biāo)
- 裝載機(jī)的基礎(chǔ)知識-裝載機(jī)的結(jié)構(gòu)及儀表
- 現(xiàn)代低壓電器技術(shù) 課件 2. 常見低壓電器
- 浙江天垣新型墻體材料有限公司年產(chǎn)40萬立方米ALC板材項目環(huán)境影響報告
- 放射事件應(yīng)急處理預(yù)案牙科
- GSV2.0反恐安全管理手冊
評論
0/150
提交評論