实例34:

  设学生信息包括学号、姓名和五门功课的成绩,要求编写输入输出学生信息的函数。在输入学生信息后,以学生成绩的总分从高到低顺序输出学生信息。

思路:

  程序引入一个结构数组依次存储输入的学生信息,为了在一组学生信息排序时避免交换整个学生结构,另外引入一个存储下标的数组。排序过程中改变学生结构下标的顺序而不是交换整个结构。

程序代码:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define N 2 //学生数据个数,练习时两三个就可以了。
#define SCORES 5 //成绩个数
#define NUMLEN 10 //允许的学号长度 //学生信息的结构体,包括:学号、姓名、五项成绩
struct std_type{
char no[NUMLEN];
char *name;
int scores[SCORES];
}; struct std_type students[N]; //定义一个学生结构体数组
//用于根据学生成绩对输出学生信息的先后进行排序
int order[N];
int total[N]; //函数读取一个学生的信息
int readastu(struct std_type *spt)
{
int len,j;
char buf[]; //输入学生的学号信息
//根据原书中的意思,是在进行错误输入时会终止,但实际上还是有些问题的
//目前我还没弄清楚是编译器的问题,还是程序的问题
//感觉像是程序的问题
printf("\nNumber : ");
if(scanf("%s",buf)==)
strncpy(spt->no,buf,NUMLEN-);
else
return ; //输入学生的姓名信息
printf("Name : ");
if(scanf("%s",buf)==)
{
len = strlen(buf);//自己不清楚缓冲区是怎么变化的,strncpy好像只是复制,好像没有清除的功能
//那么之前输入的学号(Number)也是放在buf缓冲区中,这个学号信息是被
//清除了吗?是怎么清除的?(有理解上的错误,在文末有补充)
spt->name = (char *)malloc(len+);
strcpy(spt->name,buf);
}
else
return ; //输入学生的成绩信息
printf("Scores(5 Number) : ");
for(j=; j< SCORES; j++)
{
if(scanf("%d",spt->scores+j)!=)
break;
}
if(j==)
{
free((spt->name));
return ;
}
for(;j<SCORES;j++)
spt->scores[j] = ;
return ;
} //函数输出一个学生的信息
int writeastu(struct std_type *spt)
{
int i; printf("Number : %s\n",spt->no);
printf("Name : %s\n",spt->name);
printf("Scores : ");
for(i=; i<SCORES; i++)
printf("%2d",spt->scores[i]);
printf("\n\n");
} int main()
{
int n,i,j,t;
char check_i; for(n=; n<N; n++) readastu(students+n);//此处和原书代码有些区别 //采用冒泡法对学生信息数组排序
for(i=; i<N; i++)
{
order[i] = i; //预置第i个输入的学生
for(t=,j=; j<SCORES; j++) //求第i个学生的总分
t += students[i].scores[j];
total[i] = t;
} //冒泡排序
for(i=; i<n-; i++) //共扫视n-1遍
{
for(j=; j<n--i; j++)
if(total[order[j]] < total[order[j+]])
{
t = order[j];
order[j] = order[j+];
order[j+] = t;
}
} printf("\n\nDo you want to check if your inputs are correct?(Y/N):");
scanf("%s",&check_i);
if(check_i=='y' || check_i=='Y')
for(j=; j<n; j++)
writeastu(students+order[j]);
else
return ; return ;
}

  上述代码基本上99%是原书中的源代码,但是发现对于现在的编译器来说是有问题的(WIN7+CodeBlocks16.01),其中一些不解在注释中已标注。

一、对于学生的学号来说,并不能限制错误输入。

  程序中设置的学号长度为10(NUMLEN),但实际上输入超过10个数字也是可以的,虽然输出结果会截止到10个数字。

  第32行将输入的学号放入buf中,第33行将buf中前10个字符复制到结构体的no中

二、关于缓冲区的问题

  41行中的注释是我的理解有点问题,

  第39行的代码将我们输入的字符(学生的姓名)放入到buf中,(自己理解的)会覆盖之前输入的学号,所以缓冲区其实是没什么问题的。

三、对于输入成绩来说,也不能限制输入为5

  当输入多于5个成绩时,输出会出现错误:

程序多于5个的数值会停留在缓冲区中,影响下一个学生的信息的输入,可以看下图中的例子

多于五个的成绩,02会被认为是下一个学生的学号,Ed会被认为是下一个学生的姓名;可以在第56后加一句fflush(stdin)来清空缓冲区以避免这种情况,下图是改正后的结果。

总结:程序吗,总是有可以改进的地方

C语言实例解析精粹学习笔记——34(用“结构”统计学生成绩)的更多相关文章

  1. C语言实例解析精粹学习笔记——18

    <C语言实例解析精粹>中编译环境采用的是Turbo C 2.0.但是这个编译器年代久远,较新的编译器对书中的某些例子支持不好,在学习的时候同时做一些笔记. 实例18:将一个无符号整数转换为 ...

  2. C语言实例解析精粹学习笔记——35(报数游戏)

    实例35: 设由n个人站成一圈,分别被编号1,2,3,4,……,n.第一个人从1开始报数,每报数位m的人被从圈中推测,其后的人再次从1开始报数,重复上述过程,直至所有人都从圈中退出. 实例解析: 用链 ...

  3. C语言实例解析精粹学习笔记——42(插入排序)

    实例说明: 将一个整数数组按从小到大的顺序进行排序.(主要学习基本的插入排序和改进的冒泡排序的算法和应用) 思路1: 从第一个数据开始,分别比较其后的数据,若比它小,则将这两个数的位置交换:从第一个数 ...

  4. C语言实例解析精粹学习笔记——36(模拟社会关系)

    实例: 设计一个模拟社会关系的数据结构,每个人的信息用结构表示,包含名字.性别和指向父亲.母亲.配偶.子女的指针(只限两个子女).要求编写以下函数: (1)增加一个新人的函数 (2)建立人与人之间关系 ...

  5. C语言实例解析精粹学习笔记——32

    实例32: 编制一个包含姓名.地址.邮编和电话的通讯录输入和输出函数. 思路解析: 1.用结构体来完成姓名.地址.邮编和电话的组合. 2.结构体指针的使用. 3.malloc的使用 4.scanf函数 ...

  6. C语言实例解析精粹学习笔记——31

    实例31: 判断字符串是否是回文 思路解析: 引入两个指针变量(head和tail),开始时,两指针分别指向字符串的首末字符,当两指针所指字符相等时,两指针分别向后和向前移动一个字符位置,并继续比较, ...

  7. C语言实例解析精粹学习笔记——30

    实例30: 用已知字符串s中的字符,生成由其中n个字符组成的所有字符排列.设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次.例如,对于s[]="abc",n=2, ...

  8. C语言实例解析精粹学习笔记——28

    实例28:从键盘读入实数 题目要求: 编制一个从键盘读入实数的函数readreal(double *rp).函数将读入的实数字符列转换成实数后,利用指针参数rp,将实数存于指针所指向的变量*rp. 思 ...

  9. C语言实例解析精粹学习笔记——19

    实例19:判断正整数n的d进制表示形式是否是回文数(顺着看和倒着看相同的数). 主要思路: 一种方法:将正整数n数转换成d进制的数,逐个比较首尾对应数字,判断是否为回文数. 另一种方法:将正整数n数转 ...

随机推荐

  1. 笨办法学Python(三十八)

    习题 38: 阅读代码 现在去找一些 Python 代码阅读一下.你需要自己找代码,然后从中学习一些东西.你学到的东西已经足够让你看懂一些代码了,但你可能还无法理解这些代码的功能.这节课我要教给你的是 ...

  2. WIN7系统程序放在中文文件夹打开报错及界面汉字变乱码

    今天发现在一个服务商提供的设备的WIN7系统里,一个稳定运行的程序打开时报错,且界面汉字变乱码. 经测试发现程序放在英文名称的文件夹中可以正常打开,但界面上的汉字仍为乱码. 后检查“控制面板“--”区 ...

  3. March 31 2017 Week 13 Friday

    Sometimes, you think the sky is falling down, actually, that is just because you stand slanting. 有时候 ...

  4. March 20 2017 Week 12 Monday

    A goal is a dream with a deadline. 目标就是给梦想一个期限. Dream without dealine is just daydream, because you ...

  5. March 16 2017 Week 11 Thursday

    Adventure may hurt you, but monotony will kill you. 也许冒险会让你受伤,但一成不变会让你灭亡. The very theme of the univ ...

  6. Kubernetes Helm入门指南

    什么是Helm?这可不是暗黑破坏神里装备的名称:头盔,而是Kubernetes的一个包管理工具,用来简化Kubernetes应用的部署和管理.我们Helm和Kubernetes的关系,我们可以理解成y ...

  7. 在Hibernate单向一对多关联关系中的org.hibernate.StaleStateException 异常。

    具体异常如下: Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count fro ...

  8. extension Kingfisher where Base: Image:泛型类型的具体化与实例化

    具体化:针对特定的类型参量进行二次定义: 实例化:实例化:

  9. Python语言程序设计基础(3)—— 基本数据类型

    天天向上 dayup,dayfactor = 1.0,0.01 for i in range(365): if i % 7 in [6,0]: dayup = dayup*(1-dayfactor) ...

  10. (第五场)G max 【数论】

    题目链接:https://www.nowcoder.com/acm/contest/143/G 题目描述 Give two positive integer c, n. You need to fin ...