Re: [問題] 我是學程設的新手 可以救救我嗎?

看板Programming作者 (喲)時間14年前 (2010/05/30 00:55), 編輯推噓9(9017)
留言26則, 13人參與, 最新討論串3/3 (看更多)
※ 引述《nike22puma (酷斃了你 酷!斃了你)》之銘言: : 學了程設但是聽不懂老師在說啥 : 還有 : 老師出了個回家功課但是不知道怎麼做 : EX(1)使用scanf_s()輸入五位同學各三次成績 並顯示出結果 : (2)計算每一位學生的總成績和平均值並顯示出結果 : (3)以函式呼叫方式完成第(2)項工作 : (4)當輸入值不回0-100匙顯是錯誤 : (5)以call by address 完成第(2)項工作 : 誰可以幫幫我完成 : 我會看內容但是不知道從何打起....... 不知道你對C程式的內容理解到什麼程度; 這會與"跟你討論的人該提供什麼訊息給你 較適當"有關係. scanf_s() 很少用,查一下資料說,C函式庫也有,說是"強化安全的scanf",嗯, 那就假裝是 scanf() 差不多的東西來用吧! 首先要寫個程式,先要把一些結構打好: // 開頭加一些像 #include<stdio.h> 這種引用詞 int main() { // 這裡填一些東西 } 這樣好像可以了. 你可以先寫這樣,然後編譯看看,ok之後,開始看第一題: "(1)使用scanf_s()輸入五位同學各三次成績 並顯示出結果" 「輸入?」腦中把這個問題一步一步拆開: 1. 輸入五位同學各三次成績 = 「輸入三次成績」這件事情做五次. 2. 輸入三次成績 = 「輸入成績」做三次. 3. 怎麼輸入成績? 最後就有一個問題可以開始: 怎麼輸入成績呢? 而且要用 scanf_s(). scanf_s() 要輸入一個整數, 要在主程式中寫: int main() { int n; scanf_s("%d", n ); } 「先宣告一個 n, 然後用 scanf_s 取值輸入到 n, 這樣對嗎? 然後你會注意到, 第一,使用 scanf_s() 要引用相對的函式庫標頭 stdio.h , 第二,呼叫 scanf_s() 用的參數 n 應該要給 n 的位址 &n 才找得到. 所以程式要修改成: #includ<stdio.h> int main() { int n; scanf_s("%d", &n); // 最後加個 printf("%d\n", n); 看看結果. } 好像可以了. 然後要跳到上一個問題: 怎麼輸入三個成績? 當然是用迴圈. 不過除了迴圈之外,儲存成績的變數也要延伸為陣列: #include<stdio.h> int main() { int i; int score[3]; for (i=0; i<3; i++) { scanf_s("%d", &score[i]); } /* 加入以下段落,可以檢查輸入值有沒有存進去並存得正確. for (i=0; i<3; i++) { printf("%d\n", score[i]); } */ } 接著你可能突然想到,以上程式輸入浮點數,看起來會有一點點問題. 應該是資料類型不一樣的問題. 所以程式改成: #include<stdio.h> int main() { int i; float score[3]; for (i=0; i<3; i++) { scanf_s("%f", &score[i]); } /* 加入以下段落,可以檢查輸入值有沒有存進去並存得正確. for (i=0; i<3; i++) { printf("%f\n", score[i]); } */ } 這樣感覺還不錯吧? 然後可以再往上跳一個問題: 怎麼輸入五個學生的三次成績? 每個成績要佔一個變數,五個學生各有三個成績,共要佔 15 個變數. 你可能會想用: float score[15]; 或是用: float score[5][3]; 這樣都ok的. 陣列結構不一樣,程式結構也會跟著不同而已. 先寫到這裡. 以上你可以做做看,把這一題做完. 第二個問題: 「(2)計算每一位學生的總成績和平均值並顯示出結果」 怎麼算總和? 要先知道每一個學生的每一個成績. 這裡先假設,按照前面的陣列結構,用 score[5][3] 存好了 15 個成績, 如果把它列表,看起來是: [0] [1] [2] score[0] 35 60 70 score[1] 90 70 75 score[2] 85 90 90 score[3] 40 75 70 score[4] 60 50 55 以上方陣,在第五列第一行位置 60 代表 score[4][0], 這樣你知道意思. 你知道程式中從某一段落開始,你先知道這樣的 score 陣列,就可以繼續寫下去: ... int sum = 0; for (i=0; i<3; i++) { sum = sum + score[0][i]; } /* 加上下列段落可以印出加總結果: for (i=0; i<3; i++) { printf("%d ", score[0][i]); } printf('\n'); */ } 這樣你可以先做到第一步,是將 0 號同學的三個成績加起來. 接下來,想要把五個同學的成績加起來,所以程式改成這樣: ... int sum[5]; for (i=0; i<5; i++) { for (j=0; j<3; j++) { sum[i] = sum[i] + score[i][j]; } } /* 加上下列段落可以印出加總結果: for (i=0; i<5; i++) { printf("%d\n", sum[i]); } */ } 然後執行一下,覺得好像有點問題. 往上一看, sum[0], sum[1], sum[2], ... 等等 都沒有給一個初值 0. 所以在那邊改一下: ... int sum[5]; for (i=0; i<5; i++) { sum[i] = 0; } for (i=0; i<5; i++) { for (j=0; j<3; j++) { sum[i] = sum[i] + score[i][j]; } } /* 加上下列段落可以印出加總結果: for (i=0; i<5; i++) { printf("%d ", sum[i]); } */ } 這樣就可以了. 可以加總好,就可以計算平均. 這些常識在你熟悉寫程式的過程之後, 就很容易會應用上去. 第三個問題: 「(3)以函式呼叫方式完成第(2)項工作」. 這部份你要先知道函式定義的語法要怎麼寫,然後要怎麼分配函數的工作: 也就是說,要想想哪個重覆計算的部份寫成函數. 例如: for (i=0; i<5; i++) { for (j=0; j<3; j++) { sum[i] = sum[i] + score[i][j]; } } 這個重複加總三個成績的地方太多了,也許我改寫成函數: for (i=0; i<5; i++) { sum[i] = subtotal( score[i] ); } 為什麼能寫成這樣的函數,以及 subtotal() 這樣的函數要怎麼寫, 可能是這邊你要思考的重點. 第四個問題: 「(4)當輸入值不回0-100匙顯是錯誤」 說輸入值不是0-100時顯示錯誤,這段程式應該要寫在前面 scanf_s() 附近. 那邊的原程式是: #include<stdio.h> int main() { int i; float score[3]; for (i=0; i<3; i++) { scanf_s("%f", &score[i]); } /* 加入以下段落,可以檢查輸入值有沒有存進去並存得正確. for (i=0; i<3; i++) { printf("%f\n", score[i]); } */ ... 在 scanf_s("%f", &score[i]); 這行執行之後, score[i] 都會取得一個值, 這時候可以來檢查 0-100 的限制. 所以程式在此改成: for (i=0; i<3; i++) { scanf_s("%f", &score[i]); if (score[i] < 0 || score[i] > 100) { printf("input error!"); } } 這樣,是在有輸入錯誤時印出 "input error!" 不過,顯示錯誤的方式可以很多樣,可能是在 printf("input error!"); 同句改寫成: exit(1); 直接中斷程式執行,並對外部送出一個 1 代號的訊息. 或是改成: scanf_s("%f", &score[i]); 重抓一次輸入值. 程式怎麼寫,看你的需要. 第五個問題: 「(5)以call by address 完成第(2)項工作」 這個問題較讓人看不懂,因為 "call by address" 是指先有個函式呼叫, 才來討論這個呼叫是不是 "call by address." 而第二項題目是說: : (2)計算每一位學生的總成績和平均值並顯示出結果 這裡還沒講到函式. 又或許在這裡是指 "總成績" 和 "平均值" 的計算是函式. 來看平均值的計算吧,先用第三個問題的觀點把平均值函式寫好,像是: float average(float sum, int count) { return (sum / count); } Call by address 意思是說,你呼叫 average() 的時候,如果將 sum 定義為 可以 called by address, 而且 sum 在 average() 函式中值有所改變, sum 的變化就會帶回到主程式去. 但是,目前並不需要改變 sum 的值,所以舉 sum 為例不是個好的舉例. 從 average() 來做個例子,我說,把 average() 的參數改成三個: float average(float *result, float sum, int count) { return (sum / count); } float *result 是一個可以 call by address 的參數,因為是將 result 定為 (float*). 函式定義可以改成: float averageCBA(float *result, float sum, int count) { (*result) = sum / count; return (sum / count); } 這邊會考驗你對指標的了解程度;你是否能明白指標和被指標所指的物件之間的區別. 至於以上 call by address 版本的平均值函式 averageCBA(), 呼叫的方式也有改變: ... // 假設有個 sum 和 count 變數,相對的數值都存好了. int average; averageCBA( &average, sum, count); 要用一個 average 變數接受計算結果,並同時 average 所代替參數位置是 call-by- address, 所以要取變數的位址 &average 當做參數. 以上一點討論. 你可以做練習之後,將你遇到的障礙提問. 並不是每個人都永遠拒絕提供有關作業或課堂習作的討論. ok的. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.160.211.92

05/30 00:59, , 1F
基本上,很多問問題射後不理的,您辛苦了
05/30 00:59, 1F

05/30 01:05, , 2F
這個人射後有一些回應,所以覺得多談一點無妨
05/30 01:05, 2F

05/30 01:06, , 3F
另外,也引發我自己的思考:我新手時都怎麼想.
05/30 01:06, 3F

05/30 01:10, , 4F
推認真,不過迴圈跑索引只有 0 ~ 1 喔
05/30 01:10, 4F

05/30 01:13, , 5F
有幾段的 for 條件是 < 2
05/30 01:13, 5F

05/30 01:23, , 6F
因為是片段程式,在文章的那個段落上下文所談
05/30 01:23, 6F

05/30 01:24, , 7F
迴圈的確只到0~2.. 嗯,應該要打<3才對..
05/30 01:24, 7F

05/30 01:24, , 8F
好吧,為了新手必須改文.
05/30 01:24, 8F
※ 編輯: yauhh 來自: 218.160.211.92 (05/30 01:26)

05/30 02:12, , 9F
謝謝你 我看懂了 你打的剛好是我想
05/30 02:12, 9F

05/30 02:12, , 10F
東西 我會好好認真讀的 謝謝你!!還有
05/30 02:12, 10F

05/30 02:13, , 11F
其他的大大也謝謝你們 雖然說給你們添
05/30 02:13, 11F

05/30 02:13, , 12F
了很多麻煩 謝謝你
05/30 02:13, 12F
※ 編輯: yauhh 來自: 218.160.211.92 (05/30 12:30)

05/30 12:32, , 13F
Thanks. 我也學到了很多 :)
05/30 12:32, 13F
※ 編輯: yauhh 來自: 218.160.211.92 (05/30 12:38)

05/31 08:59, , 14F
回文的人真是佛心來的.XD
05/31 08:59, 14F

05/31 22:33, , 15F
我覺得是繁中的網路討論者太兇了,高來高去,
05/31 22:33, 15F

05/31 22:34, , 16F
沒有專心以幫助人為出發點,就失去討論的價值
05/31 22:34, 16F

05/31 22:44, , 17F
不過太多人只求答案,有人費心解答就抄走
05/31 22:44, 17F

05/31 22:44, , 18F
也難怪會讓人心寒....
05/31 22:44, 18F

05/31 23:03, , 19F
其實寫程式的最嚴重了..其他板沒那麼誇張
05/31 23:03, 19F

05/31 23:03, , 20F
人家問個問題而已一大堆人又跳又罵的
05/31 23:03, 20F

06/01 12:15, , 21F
討論主要是分享想法,而非幫助人~
06/01 12:15, 21F

06/02 09:32, , 22F
y大的這個分享,也讓我去思考自己的想法
06/02 09:32, 22F

06/07 10:42, , 23F
RTFM本來是Hacket社群的風氣,不知哪時候
06/07 10:42, 23F

06/07 10:42, , 24F
一般的程式討論區也沿用了這種風氣
06/07 10:42, 24F

06/08 21:38, , 25F
寫的好詳細 佛心推
06/08 21:38, 25F

06/19 01:35, , 26F
大大真的好認真...小弟佩服
06/19 01:35, 26F
文章代碼(AID): #1C0KSBqS (Programming)
文章代碼(AID): #1C0KSBqS (Programming)