作者yauhh (喲)
看板Programming
標題Re: [問題] 我是學程設的新手 可以救救我嗎?
時間Sun May 30 00:55:35 2010
※ 引述《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
→ sw12:基本上,很多問問題射後不理的,您辛苦了 219.84.15.178 05/30 00:59
→ yauhh:這個人射後有一些回應,所以覺得多談一點無妨 218.160.211.92 05/30 01:05
→ yauhh:另外,也引發我自己的思考:我新手時都怎麼想. 218.160.211.92 05/30 01:06
推 loveme00835:推認真,不過迴圈跑索引只有 0 ~ 1 喔140.121.197.115 05/30 01:10
→ loveme00835:有幾段的 for 條件是 < 2140.121.197.115 05/30 01:13
→ yauhh:因為是片段程式,在文章的那個段落上下文所談 218.160.211.92 05/30 01:23
→ yauhh:迴圈的確只到0~2.. 嗯,應該要打<3才對.. 218.160.211.92 05/30 01:24
→ yauhh:好吧,為了新手必須改文. 218.160.211.92 05/30 01:24
※ 編輯: yauhh 來自: 218.160.211.92 (05/30 01:26)
推 nike22puma:謝謝你 我看懂了 你打的剛好是我想 61.228.147.67 05/30 02:12
→ nike22puma:東西 我會好好認真讀的 謝謝你!!還有 61.228.147.67 05/30 02:12
→ nike22puma:其他的大大也謝謝你們 雖然說給你們添 61.228.147.67 05/30 02:13
→ nike22puma:了很多麻煩 謝謝你 61.228.147.67 05/30 02:13
※ 編輯: yauhh 來自: 218.160.211.92 (05/30 12:30)
推 ijlinix:Thanks. 我也學到了很多 :)140.115.220.246 05/30 12:32
※ 編輯: yauhh 來自: 218.160.211.92 (05/30 12:38)
推 horngsh:回文的人真是佛心來的.XD112.104.191.119 05/31 08:59
→ yauhh:我覺得是繁中的網路討論者太兇了,高來高去, 218.160.210.50 05/31 22:33
→ yauhh:沒有專心以幫助人為出發點,就失去討論的價值 218.160.210.50 05/31 22:34
→ james732:不過太多人只求答案,有人費心解答就抄走 140.117.171.46 05/31 22:44
→ james732:也難怪會讓人心寒.... 140.117.171.46 05/31 22:44
推 Ross0916:其實寫程式的最嚴重了..其他板沒那麼誇張 140.112.25.140 05/31 23:03
→ Ross0916:人家問個問題而已一大堆人又跳又罵的 140.112.25.140 05/31 23:03
→ ykjiang:討論主要是分享想法,而非幫助人~ 61.230.67.186 06/01 12:15
推 iversonmin:y大的這個分享,也讓我去思考自己的想法 114.32.195.137 06/02 09:32
推 costbook:RTFM本來是Hacket社群的風氣,不知哪時候 120.124.134.62 06/07 10:42
→ costbook:一般的程式討論區也沿用了這種風氣 120.124.134.62 06/07 10:42
推 icemango:寫的好詳細 佛心推 140.123.29.25 06/08 21:38
推 glenet:大大真的好認真...小弟佩服 122.126.28.77 06/19 01:35