作者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
1F:→ sw12:基本上,很多问问题射後不理的,您辛苦了 219.84.15.178 05/30 00:59
2F:→ yauhh:这个人射後有一些回应,所以觉得多谈一点无妨 218.160.211.92 05/30 01:05
3F:→ yauhh:另外,也引发我自己的思考:我新手时都怎麽想. 218.160.211.92 05/30 01:06
4F:推 loveme00835:推认真,不过回圈跑索引只有 0 ~ 1 喔140.121.197.115 05/30 01:10
5F:→ loveme00835:有几段的 for 条件是 < 2140.121.197.115 05/30 01:13
6F:→ yauhh:因为是片段程式,在文章的那个段落上下文所谈 218.160.211.92 05/30 01:23
7F:→ yauhh:回圈的确只到0~2.. 嗯,应该要打<3才对.. 218.160.211.92 05/30 01:24
8F:→ yauhh:好吧,为了新手必须改文. 218.160.211.92 05/30 01:24
※ 编辑: yauhh 来自: 218.160.211.92 (05/30 01:26)
9F:推 nike22puma:谢谢你 我看懂了 你打的刚好是我想 61.228.147.67 05/30 02:12
10F:→ nike22puma:东西 我会好好认真读的 谢谢你!!还有 61.228.147.67 05/30 02:12
11F:→ nike22puma:其他的大大也谢谢你们 虽然说给你们添 61.228.147.67 05/30 02:13
12F:→ nike22puma:了很多麻烦 谢谢你 61.228.147.67 05/30 02:13
※ 编辑: yauhh 来自: 218.160.211.92 (05/30 12:30)
13F:推 ijlinix:Thanks. 我也学到了很多 :)140.115.220.246 05/30 12:32
※ 编辑: yauhh 来自: 218.160.211.92 (05/30 12:38)
14F:推 horngsh:回文的人真是佛心来的.XD112.104.191.119 05/31 08:59
15F:→ yauhh:我觉得是繁中的网路讨论者太凶了,高来高去, 218.160.210.50 05/31 22:33
16F:→ yauhh:没有专心以帮助人为出发点,就失去讨论的价值 218.160.210.50 05/31 22:34
17F:→ james732:不过太多人只求答案,有人费心解答就抄走 140.117.171.46 05/31 22:44
18F:→ james732:也难怪会让人心寒.... 140.117.171.46 05/31 22:44
19F:推 Ross0916:其实写程式的最严重了..其他板没那麽夸张 140.112.25.140 05/31 23:03
20F:→ Ross0916:人家问个问题而已一大堆人又跳又骂的 140.112.25.140 05/31 23:03
21F:→ ykjiang:讨论主要是分享想法,而非帮助人~ 61.230.67.186 06/01 12:15
22F:推 iversonmin:y大的这个分享,也让我去思考自己的想法 114.32.195.137 06/02 09:32
23F:推 costbook:RTFM本来是Hacket社群的风气,不知哪时候 120.124.134.62 06/07 10:42
24F:→ costbook:一般的程式讨论区也沿用了这种风气 120.124.134.62 06/07 10:42
25F:推 icemango:写的好详细 佛心推 140.123.29.25 06/08 21:38
26F:推 glenet:大大真的好认真...小弟佩服 122.126.28.77 06/19 01:35