Jack's Blog

流淌的心,怎能阻拦,吹来的风,又怎能阻挡。

工作地址转移公告

Jacob 的工作转移到

https://github.com/JinxinHu

https://www.jacobstudio.top

欢迎访问

应该还会时不时地回来看看,毕竟这里是梦想开始的地方。

立flag!

我可能真的要脱单了。


华丽分割线

好吧,反正写了也没有人看。说正事了:

要是我成功的脱单了的话,

1.我就每天早上7:00起床背单词

2.晚上10:30上床睡觉

3.学习高级流型微积分,量子力学

4.每天做一道acm题。

----来自一个单身了好几年的工科男的哀叹


更新:脱单失败。。。

1.虽然失败了,但是我依旧会将上述flag实施下来。

2.其实当初内心是不希望脱单成功的,这样的话哪有时间实施我的flag。。。

3.我要减肥,游泳,从下周起不断的完善自己。虽然就像那句老话说的:做最好的自己。不用和谁比,做最好的自己就好!

2017-10-15

哈尔滨工业大学

 

  1. 实验目的

熟悉一维、二维数组、结构体做函数参数,排序、查找、统计分析等常用算法,自顶向下、逐步求精的模块化设计思想以及增量测试方法,同时发挥出学生个人的主管能动性,创造出有意思的新功能,提高程序的健壮性和可移植性。

  1. 实验内容和要求

1.实验内容

学生成绩管理系统V6.0

某班有最多不超过30人(具体人数由键盘输入)参加期末考试,最多不超过6门(具体门数由键盘输入)。参考学生成绩管理系统V5.0,定义结构体类型,用结构体数组作函数参数,如果能够把用户输入的数据存盘,下次运行时读出,那就更有用了,编程实现如下菜单驱动的学生成绩管理系统:

(1)录入每个学生的学号、姓名和各科考试成绩;

(2)计算每门课程的总分和平均分;

(3)计算每个学生的总分和平均分;

(4)按每个学生的总分由高到低排出名次表;

(5)按每个学生的总分由低到高排出名次表;

(6)按学号由小到大排出成绩表;

(7)按姓名的字典顺序排出成绩表;

(8)按学号查询学生排名及其考试成绩;

(9)按姓名查询学生排名及其考试成绩;

(10)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比;

(11)输出每个学生的学号、姓名、各科考试成绩,以及每门课程的总分和平均分;

(12)将每个学生的记录信息写入文件;

(13)从文件中读出每个学生的记录信息并显示。

要求程序运行后先显示如下菜单,并提示用户输入选项:

Management for Students' scores

1.Input record

2.Caculate total and average score of every course

3.Caculate total and average score of every student

4.Sort in descending order by score

5.Sort in ascending order by score

6.Sort in ascending order by number

7.Sort in dictionary order by name

8.Search by number

9.Search by name

10.Statistic analysis

11.List record

12.Write to a file

13.Read from a file

0.Exit

Please Input your choice:

然后,根据用户输入的选项执行相应的操作。

 

请按照下面的定义及函数原型编程

#define   MAX_LEN  10                     /* 字符串最大长度 */

#define   STU_NUM 30                       /* 最多的学生人数 */

#define   COURSE_NUM 6                     /* 最多的考试科目数 */

typedef struct student

{

    long num;  /* 每个学生的学号 */

    char name[MAX_LEN];                   /* 每个学生的姓名 */

    float score[COURSE_NUM];      /* 每个学生COURSE_NUM门功课的成绩 */

    float sum;                       /* 每个学生的总成绩 */

    float aver;                   /* 每个学生的平均成绩 */

}STU;

int   Menu(void);

void  ReadScore(STU stu[], int n, int m);

void  AverSumofEveryStudent(STU stu[], int n, int m);

void  AverSumofEveryCourse(STU stu[], int n, int m);

void  SortbyScore(STU stu[],int n,int m,int (*compare)(float a,float b));

int   Ascending(float a, float b);

int   Descending(float a, float b);

void  SwapFloat(float *x, float *y);

void  SwapLong(long *x, long *y);

void  SwapChar(char x[], char y[]);

void  AsSortbyNum(STU stu[], int n, int m);

void  SortbyName(STU stu[], int n, int m);

void  SearchbyNum(STU stu[], int n, int m);

void  SearchbyName(STU stu[], int n, int m);

void  StatisticAnalysis(STU stu[], int n, int m);

void  PrintScore(STU stu[], int n, int m);

 

输入格式:

( 1 )录入学生的人数:

                 **要求输入数据格式为:"%d"

                 **提示信息为:"Input student number(n<30):\n"

( 2 )录入课程数:

               **要求输入数据格式为:"%d"

               **提示信息为:"Input course number(m<=%d):\n"

( 3 )录入每个学生的学号、姓名和考试成绩: 

               **要求学号、姓名的输入数据格式为:"%ld%s"

               **要求考试成绩的输入数据格式为:"%f"

               **提示信息为:"Input student's ID, name and score:\n"             

 

输出格式:

计算每门课程的总分和平均分:

              **要求输出总分与平均分格式为:"course %d:sum=%.0f,aver=%.0f\n"

计算每个学生的总分和平均分:

              **要求输出总分与平均分格式为:"student %d: sum=%.0f,aver=%.0f\n"

按成绩由高到低排出名次表:

              **要求学号、姓名的输出格式为:"%ld\t%s\t"

              **要求成绩的输出格式为:"%.0f\t"

              **要求总分及平均分的输出格式为:"%.0f\t%.0f\n"

              **提示信息为:"Sort in descending order by score:\n"

按成绩由低到高排出名次表:   

              **要求学号、姓名的输出格式为:"%ld\t%s\t"

              **要求成绩的输出格式为:"%.0f\t"

              **要求总分及平均分的输出格式为:"%.0f\t%.0f\n"

              **提示信息为:"Sort in ascending order by score:\n"

按学号由小到大排出成绩表:     

              **要求学号、姓名的输出格式为:"%ld\t%s\t"

              **要求成绩的输出格式为:"%.0f\t"

              **要求总分及平均分的输出格式为:"%.0f\t%.0f\n"

              **提示信息为:"Sort in ascending order by number:\n"

按姓名的字典顺序排出成绩表      

              **要求学号、姓名的输出格式为:"%ld\t%s\t"

              **要求成绩的输出格式为:"%.0f\t"

              **要求总分及平均分的输出格式为:"%.0f\t%.0f\n"

              **提示信息为:"Sort in dictionary order by name:\n"

按学号查询学生排名及其考试成绩:

               **如果未查到此学号的学生,提示信息为:"Not found!\n";

               **如果查询到该学生

                   # 要求学号、姓名的输出格式为:"%ld\t%s\t"

                   # 要求成绩的输出格式为:"%.0f\t"

                   # 要求总分及平均分的输出格式为:"%.0f\t%.0f\n"

               **提示信息为:"Input the number you want to search:\n"

按姓名查询学生排名及其考试成绩;

               **如果未查到此学号的学生,提示信息为:"Not found!\n";

               **如果查询到该学生

                   # 要求学号、姓名的输出格式为:"%ld\t%s\t"

                   # 要求成绩的输出格式为:"%.0f\t"

                   # 要求总分及平均分的输出格式为:"%.0f\t%.0f\n"

               **提示信息为:"Input the name you want to search:\n"

按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,统计每个类别的人数以及所占的百分比:

                **成绩<60输出提示格式为:"<60\t%d\t%.2f%%\n";

                **成绩=100输出格式为:"%d\t%d\t%.2f%%\n";

                **其他要求输出百分比格式为:"%d-%d\t%d\t%.2f%%\n"

                **提示信息为: "For course %d:\n"

输出每个学生的学号、姓名、考试成绩,以及课程总分和平均分             

              **要求学号、姓名的输出格式为:"%ld\t%s\t"

              **要求成绩的输出格式为:"%.0f\t"

              **要求总分及平均分的输出格式为:"%.0f\t%.0f\n"

选择退出(菜单项0)

                **提示信息:"End of program!"

菜单项选择错误(不在0-11之间)

                **提示信息:"Input error!\n"

 

2.实验要求

采用自顶向下、逐步求精的模块化设计思想设计一个学生管理系统。要求按系统的需求分析、系统设计(总体设计、各个模块的设计)、系统实现(各个模块的实现)、系统测试等过程组织报告内容,说明采用了什么数据结构和算法,遇到哪些问题,这些问题是如何解决的,本设计的亮点和难点在哪里,实验结果如何,有哪些收获和学习体会。

3.系统功能需求分析

学生成绩管理系统 V6.0

(1)录入每个学生的学号、姓名和各科考试成绩;

(2)计算每门课程的总分和平均分;

(3)计算每个学生的总分和平均分;

(4)按每个学生的总分由高到低排出名次表;

(5)按每个学生的总分由低到高排出名次表;

(6)按学号由小到大排出成绩表;

(7)按姓名的字典顺序排出成绩表;

(8)按学号查询学生排名及其考试成绩;

(9)按姓名查询学生排名及其考试成绩;

(10)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比;

(11)输出每个学生的学号、姓名、各科考试成绩,以及每门课程的总分和平均分;

(12)将每个学生的记录信息写入文件;

(13)从文件中读出每个学生的记录信息并显示。

要求程序运行后先显示如下菜单,并提示用户输入选项:

4.实验环境

采用了Windows 10 操作系统,使用了Codeblocks16.01的开发环境。

所需要函数库文件有<stdio.h>,<string.h>,<stdlib.h>。

  1. 系统设计

  1. 系统功能模块划分

下图是学生成绩管理系统V6.0的程序结构图

展示了该程序系统各个模块之间的结构图

 

2. 算法设计

<>1)2)3)

 

其中比较有亮点的是暗文密码输入系统,保证了输入的安全性。

3. 数据结构设计

3.1数据流图:

 

 

 

3.2顶层数据字典:

采用了结构体储存学生个人信息

#define   MAX_LEN  10                               /* 字符串最大长度 */

#define   STU_NUM 30                                   /* 最多的学生人数 */

#define   COURSE_NUM 6                          /* 最多的考试科目数 */

typedef struct student

{

      long num;                                                 /* 每个学生的学号 */

    char name[MAX_LEN];                   /* 每个学生的姓名 */

    float score[COURSE_NUM];        /* 每个学生COURSE_NUM门功课的成绩 */

    float sum;                                /* 每个学生的总成绩 */

    float aver;                                   /* 每个学生的平均成绩 */

} STU;

 

序号

字段名

字段含义

类型

长度

默认值

说明

  1.  

num

学生学号

long

10

 

 

 

0

 

 

  1.  

name

学生的姓名

char []

10

 

  1.  

score

学生每门功课的成绩

float []

6

 

  1.  

sum

学生总成绩

float

 

 

  1.  

aver

学生品均成绩

float

 

 

  1.  

stu

储存学生信息的结构体

struct []

 

 

 

4.各模块(函数)的功能和接口设计:

4.1各个模块之间的逻辑关系图

模块逻辑关系图如下:

 

  

4.2各个模块的外部接口设计

学生成绩管理系统V6.0:

  1. Main(void):

功能:完成学生数目,课程数目的录入,显示部分信息和函数调用的功能

参数:void

函数返回值:无

  1. int Menu(void);

功能:显示主菜单

参数:void

函数返回值:a(使用者选择函数的功能序号)

  1. void input(STU stu[],int stunum,int cosnum);

功能:录入每个学生的学号、姓名和各科考试成绩;

参数:

STU stu[]:存放学生信息的结构体

int stunum:学生数目的形参

int cosnum:课程数目的形参

函数返回值:无

  1. void  AverSumofEveryStudent(STU stu[], int n, int m);

功能:计算每门课程的总分和平均分;

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void  AverSumofEveryCourse(STU stu[], int n, int m);

功能:计算每个学生的总分和平均分

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void  SortbyScore(STU stu[],int n,int m,int (*compare)(float a,float b));

功能:按所给函数参数的顺序排出名次表

参数:

STU stu[]:存放学生信息的结构体

int n: 学生数目的形参

int m: 课程数目的形参

int (*compare)(float a,float b): 函数指针compare指向另一个两个浮点型形参的函数。

函数返回值:无

  1. int   Ascending(float a, float b);

功能:按每个学生的总分由低到高排出名次表

参数:

float a: 存放浮点类型数据形参

float b: 存放浮点类型数据形参

函数返回值:a<b

  1. int   Descending(float a, float b);

功能:按每个学生的总分由高到低排出名次表

参数:

float a: 存放浮点类型数据形参

float b: 存放浮点类型数据形参

函数返回值:a>b

  1. void  SwapFloat(float *x, float *y);

功能:交换两个浮点型数据的值

参数:

float *x: 存放浮点类型指针的形参

float *y: 存放浮点类型指针的形参

函数返回值:无

  1. void  SwapLong(long *x, long *y);

功能:交换两个长整型数据的值

参数:

long *x: 存放长整型类型指针的形参

long *y: 存放长整型类型指针的形参

函数返回值:无

  1. void  SwapChar(char x[], char y[]);

功能:交换两个字符串的内容

参数:

char x[]:存放字符串类型数据的形参

char y[]:存放字符串类型数据的形参

函数返回值:无

  1. void  AsSortbyNum(STU stu[], int n, int m);

功能:按学号由小到大排出成绩表;

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void  SortbyName(STU stu[], int n, int m);

功能:按姓名的字典顺序排出成绩表

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void  SearchbyNum(STU stu[], int n, int m);

功能:按学号查询学生排名及其考试成绩

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void  SearchbyName(STU stu[], int n, int m);

功能:按姓名查询学生排名及其考试成绩

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void  StatisticAnalysis(STU stu[], int n, int m);

功能:按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void  PrintScore(STU stu[], int n, int m);

功能:输出每个学生的学号、姓名、各科考试成绩,以及每门课程的总分和平均分

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void Writetofile(STU stu[],int n,int m);

功能:将每个学生的记录信息写入文件

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. void Readfromfile(STU stu[],int *n,int *m);

功能:从文件中读出每个学生的记录信息并显示

参数:

STU stu[]:存放学生信息的结构体

int m:学生数目的形参

int n:课程数目的形参

函数返回值:无

  1. 系统实现

1.系统的总流程图:

菜单驱动的系统的主流程一般为:

 

 

 

开始

 

输入学生数据

 

此学生的序数是否大于学生总数

 

从第一个学生开始排序

 

此学生成绩至少比前几位学生中一位成绩低?

 

交换与该学生位置

 

对下一位学生进行排序

 

结束

 

N

 

Y

 

N

 

Y

 

 

开始

输入所查找学生的学号

输入学号与该学生相同

从第一个学生的学号开始匹配

对下一位学生进行匹配

输出该学生的 学号 姓名 成绩

输出未查询到相关信息

结束

学号是否存在

Y

N

Y

N

 

开始

输入学生信息

目前学生数i+1

i达到最大值?

输出插入后的信息

结束

Y

N

开始

输入学生信息

程序是否进行

回车键继续

输出学生学号姓名成绩

结束

Y

N

2.程序的全部源代码:

学生管理系统V6.0

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>


#define MAX_PSD_LEN 20

#define   MAX_LEN  10                      /* 字符串最大长度 */

#define   STU_NUM 30                       /* 最多的学生人数 */

#define   COURSE_NUM 6                     /* 最多的考试科目数 */

typedef struct student

{

    long num; /* 每个学生的学号 */

    char name[MAX_LEN];                /* 每个学生的姓名 */

    float score[COURSE_NUM]; /* 每个学生COURSE_NUM门功课的成绩 */

    float sum;                       /* 每个学生的总成绩 */

    float aver;                   /* 每个学生的平均成绩 */

} STU;

inline int Menu(void)

{

    int a;

    printf("======================Welcome to the to the student info manage system v6.0==========================\n");

    printf("Management for Students' scores\n");

    printf("1.Input record\n");

    printf("2.Caculate total and average score of every course\n");

    printf("3.Caculate total and average score of every student\n");

    printf("4.Sort in descending order by score\n");

    printf("5.Sort in ascending order by score\n");

    printf("6.Sort in ascending order by number\n");

    printf("7.Sort in dictionary order by name\n");

    printf("8.Search by number\n");

    printf("9.Search by name\n");

    printf("10.Statistic analysis\n");

    printf("11.List record\n");

    printf("12.Write to a file\n");

    printf("13.Read from a file\n");

    printf("14.Sign up to Admin\n");

    printf("0.Exit\n");

    printf("=======================================================================================================\n");

    printf("Please Input your choice:\n");

STAT :

    {

        int ret=scanf(" %d",&a);

        if(ret!=1)

        {

            printf("Input Error!\nPlease enter again:\n");

            fflush(stdin);

            goto STAT;

        }

    }

    return a;

}


inline void input(STU stu[],int stunum,int cosnum)

{

    int i,j;

    printf("Input student's ID, name and score:\n");

    for (i=0; i< stunum; i++)

    {

        scanf("%ld%s",&stu[i].num,&stu[i].name);

        for(j=0; j<cosnum; j++)

        {

            scanf("%f",&stu[i].score[j]);

        }

    }

    for (i=0; i<stunum; i++)

    {

        for(j=0; j<cosnum; j++)

        {

            stu[i].sum+=stu[i].score[j];

        }

        stu[i].aver=stu[i].sum/cosnum;

    }

    return 0;

}


inline void ReadScore(STU stu[], int n, int m)

{



}


inline void AverSumofEveryStudent(STU stu[], int n, int m)

{

    int i,j;


    for (i=0; i<n; i++)

    {

        printf("student %d: sum=%.0f,aver=%.0f\n",i+1,stu[i].sum,stu[i].aver);

    }

    return 0;

}


inline void AverSumofEveryCourse(STU stu[], int n, int m)

{

    int i,j;

    float sum[COURSE_NUM]= {0},av[COURSE_NUM]= {0};

    for (i=0; i<m; i++)

    {

        for(j=0; j<n; j++)

        {

            sum[i]+=stu[j].score[i];

        }

        av[i]=sum[i]/n;

        printf("course %d:sum=%.0f,aver=%.0f\n",i+1,sum[i],av[i]);

    }


    return 0;

}

inline void SortbyScore(STU stu[],int n,int m,int (*compare)(float a,float b))

{

    int i,j,k,ii;


    for(i=0; i<n-1; i++)

    {

        k=i;

        for(j=i+1; j<n; j++)

        {

            if((*compare)(stu[j].aver,stu[k].aver))

                k=j;

        }

        if(k!=i)

        {

            SwapFloat(&stu[k].aver,&stu[i].aver);

            SwapFloat(&stu[k].sum,&stu[i].sum);

            SwapChar(stu[k].name,stu[i].name);

            SwapLong(&stu[k].num,&stu[i].num);

            for(ii=0; ii<m; ii++)

            {

                SwapFloat(&stu[k].score[ii],&stu[i].score[ii]);

            }

        }

    }

    return 0;

}


inline int Ascending(float a, float b)    /*按每个学生的总分由高到低排出名次表*/

{

    return a<b;

}


inline int Descending(float a, float b)

{

    return a>b;

}


inline void SwapFloat(float *x, float *y)

{

    float t2;


    t2=*x;

    *x=*y;

    *y=t2;

    return 0;

}

inline void SwapLong(long *x, long *y)

{

    long t1;


    t1=*x;

    *x=*y;

    *y=t1;

    return 0;

}

inline void SwapChar(char x[], char y[])

{

    char str[MAX_LEN];


    strcpy(str,x);

    strcpy(x,y);

    strcpy(y,str);

    return 0;

}

inline void AsSortbyNum(STU stu[], int n, int m)

{

    int i,j,k,ii;


    for(i=0; i<n-1; i++)

    {

        k=i;

        for(j=i+1; j<n; j++)

        {

            if(stu[j].num<stu[k].num)

                k=j;

        }

        if(k!=i)

        {

            SwapFloat(&stu[k].aver,&stu[i].aver);

            SwapFloat(&stu[k].sum,&stu[i].sum);

            SwapChar(stu[k].name,stu[i].name);

            SwapLong(&stu[k].num,&stu[i].num);

            for(ii=0; ii<m; ii++)

            {

                SwapFloat(&stu[k].score[ii],&stu[i].score[ii]);

            }

        }

    }

    return 0;

}

inline void SortbyName(STU stu[], int n, int m)

{

    int i,j,k,ii;


    for(i=0; i<n-1; i++)

    {

        k=i;

        for(j=i+1; j<n; j++)

        {

            if(strcmp(stu[j].name,stu[k].name)<0)

                k=j;

        }

        if(k!=i)

        {

            SwapFloat(&stu[k].aver,&stu[i].aver);

            SwapFloat(&stu[k].sum,&stu[i].sum);

            SwapChar(stu[k].name,stu[i].name);

            SwapLong(&stu[k].num,&stu[i].num);

            for(ii=0; ii<m; ii++)

            {

                SwapFloat(&stu[k].score[ii],&stu[i].score[ii]);

            }

        }

    }



}

inline void SearchbyNum(STU stu[], int n, int m)

{

    long number;

    int i,j,ii;


    printf("Input the number you want to search:\n");

    scanf("%ld",&number);

    for(i=0; i<n; i++)

    {

        if(stu[i].num==number)

        {

            printf("%ld\t%s\t",stu[i].num,stu[i].name);

            for(j=0; j<m; j++)

                printf("%.0f\t",stu[i].score[j]);


            printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);

            return 0;

        }

    }

    printf("Not found!\n");

    return 0;

}

inline void SearchbyName(STU stu[], int n, int m)

{

    int i,j;

    char stuname[MAX_LEN];


    printf("Input the name you want to search:\n");

    scanf("%s",stuname);

    for(i=0; i<n; i++)

    {

        if(!strcmp(stuname,stu[i].name))

        {

            printf("%ld\t%s\t",stu[i].num,stu[i].name);

            for(j=0; j<m; j++)

                printf("%.0f\t",stu[i].score[j]);


            printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);

            return 0;

        }

    }

    printf("Not found!\n");

    return 0;

}

inline void StatisticAnalysis(STU stu[], int n, int m)

{

    int i,j,total;

    for(j=0; j<m; j++)

    {

        int t[COURSE_NUM]= {0};

        printf("For course %d:\n",j+1);

        for(i=0; i<n; i++)

        {

            if(stu[i].score[j]>=0&&stu[i].score[j]<60)

                t[0]++;

            else if(stu[i].score[j]<70)

                t[1]++;

            else if(stu[i].score[j]<80)

                t[2]++;

            else if(stu[i].score[j]<90)

                t[3]++;

            else if(stu[i].score[j]<100)

                t[4]++;

            else if(stu[i].score[j]==100)

                t[5]++;

        }

        for(i=0; i<6; i++)

        {

            if(i==0)

                printf("<60\t%d\t%.2f%%\n",t[i],(float)t[i]/n*100);

            else if(i==5)

                printf("%d\t%d\t%.2f%%\n",(i+5)*10,t[i],(float)t[i]/n*100);

            else

            {

                printf("%d-%d\t%d\t%.2f%%\n",(i+5)*10,(i+5)*10+9,t[i],(float)t[i]/n*100);

            }

        }

    }

    return 0;

}


inline void PrintScore(STU stu[], int n, int m)

{

    int i,j;

    for (i=0; i< n; i++)

    {

        printf("%ld\t%s\t",stu[i].num,stu[i].name);

        for(j=0; j<m; j++)

            printf("%.0f\t",stu[i].score[j]);


        printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);

    }

}


inline void Writetofile(STU stu[],int n,int m)

{

    FILE *fp;

    int i,j;


    if((fp=fopen("student.txt","w"))== NULL)

    {


        printf("Failure to open score.txt! \n");

        exit(1);

    }

    fprintf(fp,"%d\t%d\n",n,m);

    for(i=0; i<n; i++)

    {

        fprintf(fp,"%10ld%10s",stu[i].num,stu[i].name);

        for(j=0; j<m; j++)

        {


            fprintf(fp,"%10.0f",stu[i].score[j]);

        }

        fprintf(fp,"%10.0f%10.0f\n",stu[i].sum,stu[i].aver);

    }

    fclose(fp);

    return 0;

}


inline void Readfromfile(STU stu[],int *n,int *m)

{

    FILE *fp;

    int i,j;


    if((fp=fopen("student.txt","r"))== NULL)

    {


        printf("Failure to open score.txt! \n");

        exit(1);

    }

    fscanf(fp,"%d\t%d",n,m);

    for(i=0; i<*n; i++)

    {

        fscanf(fp,"%10ld",&stu[i].num);

        fscanf(fp,"%10s",stu[i].name);

        for(j=0; j<*m; j++)

        {


            fscanf(fp,"%10f",&stu[i].score[j]);

        }

        fscanf(fp,"%10f%10f\n",&stu[i].sum,&stu[i].aver);

    }

    fclose(fp);

    return 0;

}


inline admin(STU stu[],int n,int m)

{

    printf("========================Welcome to the to the admin version=========================\n");

    printf("You have 2 options.\n");

    printf("1.login.\n");

    printf("2.exit.\n");

    printf("3.change your password.\n");

printf("=====================================================================================\n");

    char pw[MAX_PSD_LEN]="admin",pw2[MAX_PSD_LEN]="123456";

    int a;

    char PassWord[MAX_PSD_LEN],*p=PassWord,ch;

    char PassWord1[MAX_PSD_LEN],*p1=PassWord1,*p2=pw2;

    int count=0;


    printf("Please select your option!\n");

    scanf("%d",&a);


    if(a==1)

    {

        printf("Please Enter your password:\n");

        ch=getch();

        while(ch!=13&&count<MAX_PSD_LEN-1)       /*当按下回车键或密码长度达到19,则退出循环*/

        {

            if(ch==8)                       /*如果按下的是向前删除键,则...*/

            {

                if(count)              /*如果密码串中字符数大于零,则向前删除一个字符*/

                {

                    p--;

                    count--;

                    printf("\b ");/*光标回退一格,将星号(*)改为空格*/

                    printf("\b"); /*光标重新回退一格*/

                }

            }

            else if((ch<='Z'&&ch>='A')||(ch<='z'&&ch>='a')||(ch<='9'&&ch>='0'))

                /*如果输入的是密码的有效字符*/

            {

                printf("*");          /*输出一个星号*/

                count++;

                *p=ch;                /*记录密码内容*/

                p++;

            }

            ch=getch();                    /*等待输入下一个字符*/

        }

        PassWord[count]=0;

        printf("\n");

        if(strcmp(PassWord,pw)==0)

        {


            printf("You have successfully login!\n");

            n=adminsystem(stu,n,m);

            return n;

        }

        else

        {

            printf("Your password isn't correct!\n");

            return n;

        }

    }


    else if(a==2)

    {


        printf("You have successfully exit the Admin system!\n");

        return n;

    }

    else if(a==3)

    {

        count=0;

        printf("Please enter your old password:\n");

        ch=getch();

        while(ch!=13&&count<MAX_PSD_LEN-1)       /*当按下回车键或密码长度达到19,则退出循环*/

        {

            if(ch==8)                       /*如果按下的是向前删除键,则...*/

            {

                if(count)              /*如果密码串中字符数大于零,则向前删除一个字符*/

                {

                    p--;

                    count--;

                    printf("\b ");/*光标回退一格,将星号(*)改为空格*/

                    printf("\b"); /*光标重新回退一格*/

                }

            }

            else if((ch<='Z'&&ch>='A')||(ch<='z'&&ch>='a')||(ch<='9'&&ch>='0'))

                /*如果输入的是密码的有效字符*/

            {

                printf("*");          /*输出一个星号*/

                count++;

                *p=ch;                /*记录密码内容*/

                p++;

            }

            ch=getch();                    /*等待输入下一个字符*/

        }

        PassWord[count]=0;

        printf("\n");

        if(strcmp(PassWord,pw)==0)

        {

            count=0;


            printf("Congratulations!Please enter your new password:\n");

            ch=getch();

            while(ch!=13&&count<MAX_PSD_LEN-1)       /*当按下回车键或密码长度达到19,则退出循环*/

            {

                if(ch==8)                       /*如果按下的是向前删除键,则...*/

                {

                    if(count)              /*如果密码串中字符数大于零,则向前删除一个字符*/

                    {

                        p2--;

                        count--;

                        printf("\b ");/*光标回退一格,将星号(*)改为空格*/

                        printf("\b"); /*光标重新回退一格*/

                    }

                }

                else if((ch<='Z'&&ch>='A')||(ch<='z'&&ch>='a')||(ch<='9'&&ch>='0'))

                    /*如果输入的是密码的有效字符*/

                {

                    printf("*");          /*输出一个星号*/

                    count++;

                    *p2=ch;                /*记录密码内容*/

                    p2++;

                }

                ch=getch();                    /*等待输入下一个字符*/

            }

            pw2[count]=0;

            printf("\n");

            printf("Please enter again:\n");


            count=0;

            ch=getch();

            while(ch!=13&&count<MAX_PSD_LEN-1)       /*当按下回车键或密码长度达到19,则退出循环*/

            {

                if(ch==8)                       /*如果按下的是向前删除键,则...*/

                {

                    if(count)              /*如果密码串中字符数大于零,则向前删除一个字符*/

                    {

                        p1--;

                        count--;

                        printf("\b ");/*光标回退一格,将星号(*)改为空格*/

                        printf("\b"); /*光标重新回退一格*/

                    }

                }

                else if((ch<='Z'&&ch>='A')||(ch<='z'&&ch>='a')||(ch<='9'&&ch>='0'))

                    /*如果输入的是密码的有效字符*/

                {

                    printf("*");          /*输出一个星号*/

                    count++;

                    *p1=ch;                /*记录密码内容*/

                    p1++;

                }

                ch=getch();                    /*等待输入下一个字符*/

            }

            PassWord1[count]=0;

            printf("\n");

            if(!strcmp(PassWord1,pw2))

            {

                strcpy(pw,PassWord1);

                printf("Your password has been successfully changed!\n");

                return n;

            }

            else

                printf("tow times does NOT match!\n");

                return n;

            }


        else

        {

            printf("Your password isn't correct!\n");

            return n;

        }


    }

    else

    {

        printf("Input Error!\n");

        return n;

    }


}

inline adminsystem(STU stu[],int n,int m)

{

    int n1;

    long num;

    char x;


    printf("1.add a student info\t\n");

    printf("2.delete a student info\t\n");

    printf("3.exit\n");

    scanf("%d",&n1);

    switch(n1)

    {

    case 1:

    {

        printf("please enter the student number you want to add:");

        num=-1;

        while(num<0)

        {

            scanf("%ld",&num);

            printf("\n");

            if(num<=0)

                printf("Input Error!\n""Please enter again:\n");

        }


        int i,j;


        printf("Input to be added student's ID, name and score:\n");

        for (i=0; i<num; i++)

        {

            scanf("%ld%s",&stu[n+i].num,&stu[n+i].name);

            for(j=0; j<m; j++)

            {

                scanf("%f",&stu[i+n].score[j]);

            }

        }

        for (i=0; i<num; i++)

        {

            for(j=0; j<m; j++)

            {

                stu[i+n].sum+=stu[i+n].score[j];

            }

            stu[i+n].aver=stu[i+n].sum/m;

            n=n+num;

            return n;

        }

        break;

        case 2:

        {

            printf("Please enter the student's student number you want to delete:\n");

            scanf("%ld",&num);


            int i,j;

            for(i=0; i<n; i++)

            {

                if(stu[i].num==num)

                {

                    printf("%ld\t%s\t",stu[i].num,stu[i].name);

                    for(j=0; j<m; j++)

                        printf("%.0f\t",stu[i].score[j]);


                    printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);


                    printf("Are you SURE to delete(y/n)?\n");

                    scanf(" %c",&x);

                    char name1[MAX_LEN]= {0};


                    if(x=='y'||x=='Y')

                    {

                        stu[i].num=0;

                        strcpy(stu[i].name,name1);

                        for(j=0; j<m; j++)

                            stu[i].score[j]=0;


                        stu[i].sum=0;

                        stu[i].aver=0;

                        return n=n-1;

                    }

                    else if(x=='n'||x=='N')

                    {


                        return n;

                    }

                    else

                        printf("Input Error!\n");

                    return n;

                }

            }

            printf("Not found!\n");

            return n;

        }

        break;

        case 3:

            return n;

        default:

            printf("Input Error!");

            return n;

        }


    }

}

int main()

{

    int stunum=-1,cosnum=-1;


    while(stunum<0||stunum>30)

    {

        printf("Input student number(n<=30):\n");

        scanf("%d",&stunum);

        if(stunum<0||stunum>30)

        {


            printf("Input Error!Please Enter Again:\n");

        }

    }

    while(cosnum<0||cosnum>6)

    {

        printf("Input course number(m<=%d):\n",COURSE_NUM);

        scanf("%d",&cosnum);

        if(cosnum<0||cosnum>6)

        {


            printf("Input Error!Please Enter Again:\n");

        }

    }


    STU stu[STU_NUM]= {0};


    int flag=1,a,i,j;

    while(flag)

    {

        a=Menu();

        switch (a)

        {

        case 1:

            input(stu,stunum,cosnum);

            break;

        case 2:

            AverSumofEveryCourse(stu,stunum,cosnum);

            break;

        case 3:

            AverSumofEveryStudent(stu,stunum,cosnum);

            break;

        case 4:

            SortbyScore(stu,stunum,cosnum,Descending);

            printf("Sort in descending order by score:\n");

            for (i=0; i< stunum; i++)

            {

                printf("%ld\t%s\t",stu[i].num,stu[i].name);

                for(j=0; j<cosnum; j++)

                    printf("%.0f\t",stu[i].score[j]);


                printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);

            }

            break;

        case 5:

            SortbyScore(stu,stunum,cosnum,Ascending);

            printf("Sort in ascending order by score:\n");

            for (i=0; i< stunum; i++)

            {

                printf("%ld\t%s\t",stu[i].num,stu[i].name);

                for(j=0; j<cosnum; j++)

                    printf("%.0f\t",stu[i].score[j]);


                printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);

            }

            break;

        case 6:

            printf("Sort in ascending order by number:\n");

            AsSortbyNum(stu,stunum,cosnum);

            for (i=0; i< stunum; i++)

            {

                printf("%ld\t%s\t",stu[i].num,stu[i].name);

                for(j=0; j<cosnum; j++)

                    printf("%.0f\t",stu[i].score[j]);


                printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);

            }

            break;

        case 7:

            printf("Sort in dictionary order by name:\n");

            SortbyName(stu,stunum,cosnum);

            for (i=0; i< stunum; i++)

            {

                printf("%ld\t%s\t",stu[i].num,stu[i].name);

                for(j=0; j<cosnum; j++)

                    printf("%.0f\t",stu[i].score[j]);


                printf("%.0f\t%.0f\n",stu[i].sum,stu[i].aver);

            }

            break;

        case 8:

            SearchbyNum(stu,stunum,cosnum);

            break;

        case 9:

            SearchbyName(stu,stunum,cosnum);

            break;

        case 10:

            StatisticAnalysis(stu,stunum,cosnum);

            break;

        case 11:

            PrintScore(stu,stunum,cosnum);

            break;

        case 12:

            Writetofile(stu,stunum,cosnum);

            break;

        case 13:

            Readfromfile(stu,&stunum,&cosnum);

            break;

        case 14:

            stunum=admin(stu,stunum,cosnum);

            break;

        case 0:

            printf("End of program!\n");

            flag=0;

            exit(0);

        default:

            printf("Input error!\n");

        }

    }

    return 0;

}
  1. 系统测试

1.程序调试中遇到的问题和解决方法及思路

在调试过中,我并没有碰到一些难点问题。只是程序调试的过程中会出现一些小错误,我通过单步执行,一点点找到错误,分析出错误的原因,然后逐个地更正错误,最后让程序更加完善。

举个例子,在用户在菜单界面进行选择菜单输入数字时候,不小心输成了英文,这会使得scanf读取错误,系统会无限循环,进而造成程序安乐死。

于是,我通过使用scanf函数的return值来进行判断,是否带到要求,并同时用fflush(stdin)进行清空缓冲区,这样问题就完美解决了。

2.实验结果

略。

  1. 分析总结、收获和体会

通过这次C语言实验设计,我发现其实设计一个如此长的系统并不是一件非常难的事情,然而将这个系统完善好才是比较难的一件事。尤其是在Debug过程中出现了许多问题,有些问题,一找就是一两个小时,十分令人头疼。写程序容易改程序难啊!

在写程序的过程中,了解到了之前没学过的一些知识,比如

  1. system(“cls”);是一个清屏函数;

  2. getchar();是程序停滞时使用的;

  3. 学习编写了暗文密码的输入系统,原来我们平时日常生活中经常输入的账户密码看不见原来是这个原理;

  4. 学会了文件的基本操作;

  5. inline (内联函数)的使用:内联函数的代码会在任何调用它的地方展开,使得程序占用内存空间更少;

  6. 采用了函数指针,将程序中的升序和降序两个函数抽象成一个独立的通用排序函数,使程序更加简洁,提高了程序的通用性,减少了重复代码。

在写程序的过程中我也总结出来了几点经验:

  1. 在程序的开始或者相关函数调用的时候增加一段错误处理代码。可以增加整个工程的容错性,提高程序的使用性能;

  2. 将程序中的绝对路径引用改为相对路径引用可以提高整个程序的移植性能;

  3. 多打备注有利于检查;

  4. 函数的模块化思想有利于程序的debug,也有利于提高程序的通用性,减少重复代码。

在这次设计中,我的优点不仅是将上述的经验和知识运用到我的代码中去,而且我也将程序写的非常标准,不省略任何一个return 0;对程序健壮性也做了优化,即使在输入菜单时不小心输入错了,程序也不会卡死,会重新让用户输入。

当然,在写代码的时候我也发现了我的许多不足,比如说一些基本功不扎实,老犯一些低级错误,导致程序出错,要解决这个问题,编程序的时候一定要细心,多看看书,多看些典型的算法,扎实基本功。还有一件重要的事情就是程序的美观性,以后的系统可以通过使用不同的颜色,不同的样式,更多的图片,来使得程序更加美观,让用户使用的时候心情舒畅。

完成这次大作业后,我不惧怕再编一个更长甚至更复杂的系统,只要静下心来,将系统划分成各个模块,分别击破,一个更宏大的操作系统就完成了,并非想象中的那么困难,原来我也可以编出这样的系统。将编程当做一件快乐的事情去做。

通往一名合格的程序员之路还有很长,在计算机编程中还有好多新的东西等待我们去探索,更底层的语言值得我们学习,更高级的语言值得我们去寻味。因此,我打算在今后的两年里面逐步学习JAVA,PYTHON,APP开发,汇编语言学习等等,极大地开发自己在计算机领域的兴趣。

要成为一名高级程序员,我还需要一路披荆斩棘,克服困难,不懈努力!

参考文献

[1] 苏小红,王宇颖,孙志岗.C语言程序设计(第3版)[M].北京:高等教育出版社.2015

[2] 苏小红,王宇颖,孙志岗.C语言程序设计学习指导(第3版)[M].北京:高等教育出版社.2015

[3] Stephen Prata.C Primer Plus中文版(第六版)[M].北京:人民邮电出版社.2016

学生管理系统V1.0

Q3134.(10分)第8章实验1:学生成绩管理系统V1.0
某班有最多不超过30人(具体人数由键盘输入)参加某门课程的考试,用一维数组作函数参数编程实现如下学生成绩管理:
(1)录入每个学生的学号和考试成绩;
(2)计算课程的总分和平均分;
(3)按成绩由高到低排出名次表;
(4)按学号由小到大排出成绩表;
(5)按学号查询学生排名及其考试成绩;
(6)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,统计每个类别的人数以及所占的百分比;
(7)输出每个学生的学号、考试成绩。

程序运行结果示例:
Input student number(n<30):
6↙
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
1↙
Input student's ID, name and score:
11003001 87↙
11003005 98↙
11003003 75↙
11003002 48↙
11003004 65↙
11003006 100↙
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
2↙
sum=473,aver=78.83
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
3↙
Sort in descending order by score:
11003006 100
11003005 98
11003001 87
11003003 75
11003004 65
11003002 48
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
4↙
Sort in ascending order by number:
11003001 87
11003002 48
11003003 75
11003004 65
11003005 98
11003006 100
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
5↙
Input the number you want to search:
11003004
11003004 65
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
6↙
<60 1 16.67%
60-69 1 16.67%
70-79 1 16.67%
80-89 1 16.67%
90-99 1 16.67%
100 1 16.67%
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
7↙
11003001 87
11003002 48
11003003 75
11003004 65
11003005 98
11003006 100
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
8↙
Input error!
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
0↙
End of program!

输入格式:
( 1 )录入学生的人数:
                 **输入数据格式:"%d"
                 **提示信息:"Input student number(n<30):\n"
( 2 )录入每个学生的学号和考试成绩:
               **输入数据格式:"%ld%f"
               **提示信息:"Input student's ID, name and score:\n"
输出格式:
菜单项的输出显示:
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
计算课程的总分和平均分:
              **输出总分与平均分格式:"sum=%.0f,aver=%.2f\n"
按成绩由高到低排出名次表:
              **输出格式:"%ld\t%.0f\n"
              **提示信息:"Sort in descending order by score:\n"
按学号由小到大排出成绩表:
              **输出格式:"%ld\t%.0f\n"
              **提示信息:"Sort in ascending order by number:\n"
按学号查询学生排名及其考试成绩:
               **如果未查到此学号的学生,提示信息:"Not found!\n"
               **如果查询到该学生,输出格式:"%ld\t%.0f\n"
按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,统计每个类别的人数以及所占的百分比:
                **成绩<60输出格式:"<60\t%d\t%.2f%%\n"
                **成绩=100输出格式:"%d\t%d\t%.2f%%\n"
                **其他输出百分比格式:"%d-%d\t%d\t%.2f%%\n"

#include"stdio.h"
int input(unsigned long *p,float *q,int k)
{
   int i,j;
   printf("Input student's ID, name and score:\n");
   for (i=0;i< k;i++)
       scanf("%ld%f",p+i,q+i);
   return 0;
}
int cal(float *p,int k)
{
   int i;float sum=0,av=0;
   for (i=0;i< k;i++)
       sum+=*(p+i);
   av=sum/k;
   printf("sum=%.0f,aver=%.2f\n",sum,av);
   return 0;
}
int swap(unsigned long *p,float *q,int i,int j)
{
   unsigned long t1;float t2;
   t1=*(p+i);
   *(p+i)=*(p+j);
   *(p+j)=t1;
   t2=*(q+i);
   *(q+i)=*(q+j);
   *(q+j)=t2;
 
   return 0;
}
int sortsc(unsigned long *p,float *q,int k)
{
   int i,j,max;
   for (i=0;i< k-1;i++)
   {
       max=i;
       for (j=i+1;j< k;j++)
           if (*(q+j)>*(q+max)) max=j;
       swap(p,q,i,max);
   }
 
   return 0;
}
int sortst(unsigned long *p,float *q,int k)
{
   int i,j,max;
   for (i=0;i< k-1;i++)
   {
       max=i;
       for (j=i+1;j< k;j++)
           if (*(p+j)<*(p+max)) max=j;
       swap(p,q,i,max);
   }
 
   return 0;
}
int sebn(unsigned long *p,float *q,int k)
{
   unsigned long sc;
   int i,ans=k;
   printf("Input the number you want to search:\n");
   scanf("%ld",&sc);
   for (i=0;i< k;i++)
       if (*(p+i)==sc) ans=i;
   if (ans!=k) printf("%ld\t%.0f\n",*(p+ans),*(q+ans));
   else printf("Not found!\n");
 
   return 0;
}
int stan(float *q,int k)
{
   int num[6],i;
   for (i=0;i< 6;i++) num[i]=0;
   for (i=0;i< k;i++)
   {
       if (*(q+i)>99) {num[0]++;continue;}
       if (*(q+i)>89) {num[1]++;continue;}
       if (*(q+i)>79) {num[2]++;continue;}
       if (*(q+i)>69) {num[3]++;continue;}
       if (*(q+i)>59) {num[4]++;continue;}
                      {num[5]++;}
   }
   printf("<60\t%d\t%.2f%%\n",num[5],100.0*num[5]/k);
   printf("60-69\t%d\t%.2f%%\n",num[4],100.0*num[4]/k);
   printf("70-79\t%d\t%.2f%%\n",num[3],100.0*num[3]/k);
   printf("80-89\t%d\t%.2f%%\n",num[2],100.0*num[2]/k);
   printf("90-99\t%d\t%.2f%%\n",num[1],100.0*num[1]/k);
   printf("100\t%d\t%.2f%%\n",num[0],100.0*num[0]/k);
 
   return 0;
}
int main()
{
  int n,flag=1,a,i;
  float sc[30];
  unsigned long st[30];
  printf("Input student number(n<30):\n");
  scanf("%d",&n);
  while(flag)
  {
       printf("Management for Students' scores\n");
       printf("1.Input record\n");
       printf("2.Caculate total and average score of course\n");
       printf("3.Sort in descending order by score\n");
       printf("4.Sort in ascending order by number\n");
       printf("5.Search by number\n");
       printf("6.Statistic analysis\n");
       printf("7.List record\n");
       printf("0.Exit\n");
       printf("Please Input your choice:\n");
       scanf("%d",&a);
       switch (a)
       {
           case 1:
               input(st,sc,n);
               break;
           case 2:
               cal(sc,n);
               break;
           case 3:
               sortsc(st,sc,n);
               printf("Sort in descending order by score:\n");
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 4:
               sortst(st,sc,n);
               printf("Sort in ascending order by number:\n");
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 5:
               sebn(st,sc,n);
               break;
           case 6:
               stan(sc,n);
               break;
           case 7:
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 0:
               flag=0;
               printf("End of program!\n");
               break;
           default:
               printf("Input error!\n");
       }
 
  }
 
  return 0;
}

C语言学习四

C语言中main函数return的总结

在函数中,如果碰到return 语句,那么程序就会返回调用该函数的下一条语句执行,也就是说跳出函数的执行,回到原来的地方继续执行下去。但是如果是在主函数中碰到return语句,那么整个程序就会停止,退出程序的执行。

return是C++预定义的语句,它提供了种植函数执行的一种放大。当return语句提供了一个值时,这个值就成为函数的返回值.

说到return,有必要提及主函数的定义,下面是从网络上找到的资料,好好消化吧,对了解主函数中返回值的理解有很大的帮助.

很多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void main( ) 。C++ 之父 Bjarne Stroustrup 在他的主页上的 FAQ 中明确地写着 The definition void main( ) { /* ... */ } is not and never has been C++, nor has it even been C.( void main( ) 从来就不存在于 C++ 或者 C )。下面我分别说一下 C 和 C++ 标准中对 main 函数的定义。


1. C
在 C89 中,main( ) 是可以接受的。Brian W. Kernighan 和 Dennis M. Ritchie 的经典巨著 The C programming Language 2e(《C 程序设计语言第二版》)用的就是 main( )。不过在最新的 C99 标准中,只有以下两种定义方式是正确的:
int main( void )
int main( int argc, char *argv[] )
(参考资料:ISO/IEC 9899:1999 (E) Programming languages — C 5.1.2.2.1 Program startup)
当然,我们也可以做一点小小的改动。例如:char *argv[] 可以写成 char **argv;argv 和 argc 可以改成别的变量名(如 intval 和 charval),不过一定要符合变量的命名规则。

如果不需要从命令行中获取参数,请用int main(void) ;否则请用int main( int argc, char *argv[] ) 。
main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统)。

如果 main 函数的最后没有写 return 语句的话,C99 规定编译器要自动在生成的目标文件中(如 exe 文件)加入return 0; ,表示程序正常退出。不过,我还是建议你最好在main函数的最后加上return 语句,虽然没有这个必要,但这是一个好的习惯。注意,vc6不会在目标文件中加入return 0; ,大概是因为 vc6 是 98 年的产品,所以才不支持这个特性。现在明白我为什么建议你最好加上 return 语句了吧!不过,gcc3.2(Linux 下的 C 编译器)会在生成的目标文件中加入 return 0; 。

2. C++
C++98 中定义了如下两种 main 函数的定义方式:
int main( )
int main( int argc, char *argv[] )
(参考资料:ISO/IEC 14882(1998-9-01)Programming languages — C++ 3.6 Start and termination)
int main( ) 等同于 C99 中的 int main( void ) ;int main( int argc, char *argv[] ) 的用法也和 C99 中定义的一样。同样,main 函数的返回值类型也必须是int。如果main函数的末尾没写return语句,C++98 规定编译器要自动在生成的目标文件中加入 return 0; 。同样,vc6 也不支持这个特性,但是 g++3.2(Linux 下的 C++ 编译器)支持。

3. 关于 void main
在 C 和 C++ 中,不接收任何参数也不返回任何信息的函数原型为“void foo(void);”。可能正是因为这个,所以很多人都误认为如果不需要程序返回值时可以把main函数定义成void main(void) 。然而这是错误的!main 函数的返回值应该定义为 int 类型,C 和 C++ 标准中都是这样规定的。虽然在一些编译器中,void main 可以通过编译(如 vc6),但并非所有编译器都支持 void main ,因为标准中从来没有定义过 void main 。g++3.2 中如果 main 函数的返回值不是 int 类型,就根本通不过编译。而 gcc3.2 则会发出警告。所以,如果你想你的程序拥有很好的可移植性,请一定要用 int main 。

4. 返回值的作用
main 函数的返回值用于说明程序的退出状态。如果返回 0,则代表程序正常退出,否则代表程序异常退出。下面我们在 winxp 环境下做一个小实验。首先编译下面的程序:
int main( void )
{
return 0;
}
然后打开附件里的“命令提示符”,在命令行里运行刚才编译好的可执行文件,然后输入“echo %ERRORLEVEL%”,回车,就可以看到程序的返回值为 0 。假设刚才编译好的文件是 a.exe ,如果输入“a && dir”,则会列出当前目录下的文件夹和文件。但是如果改成“return -1”,或者别的非 0 值,重新编译后输入“a && dir”,则 dir 不会执行。因为 && 的含义是:如果 && 前面的程序正常退出,则继续执行 && 后面的程序,否则不执行。也就是说,利用程序的返回值,我们可以控制要不要执行下一个程序。这就是 int main 的好处。 如果你有兴趣,也可以把 main 函数的返回值类型改成非 int 类型(如 float),重新编译后执行“a && dir”,看看会出现什么情况,想想为什么会出现那样的情况。顺便提一下,如果输入 a || dir 的话,则表示如果 a 异常退出,则执行 dir 。


5. 那么 int main(intargc,char*argv[],char*envp[])呢?
  这当然也不是标准 C 里面定义的东西!char*envp[] 是某些编译器提供的扩展功能,用于获取系统的环境变量。因为不是标准,所以并非所有编译器都支持,故而移植性差,不推荐使用。
到了这里,你应该了解为什么主函数定义为 int返回类型,而且函数体里面有return 0;这个语句了吧.
下面具体说说我对return的应用的理解。

只要一个函数的返回值是数字型的,那么就可以返回0(即return 0),其实你返回多少都没问题。一 般情况下,C++做出来的函数都要求返回一个值,当函数执行正常,且达到了一般情况下的目的,那么就返回0表示正确的调用了该函数,这个0就是返回给主调 函数以通知没有出错的;如果函数调用中出错,或者没有按照一般情况执行,那么就返回1,以告知主调函数采取响应策略;如果你在某个函数所在类的定义所在的 头文件中定义了一组状态值(一般都是负整数),那么函数就可以返回不同的值以告之主调函数具体发生了什么异常或错误,这种情况一般用于函数功能独立性较差 的的情况。所以一般不鼓励把函数返回类型定义为void,至少返回应该是int,而在函数的最后加上return 0.语句:
int func(参数列表)
{
……
……
……
Return 0;
}
在函数中,如果碰到return 语句,那么程序就会返回调用该函数的下一条语句执行,也就是说跳出函数的执行,回到原来的地方继续执行下去。但是如果是在主函数中碰到return语句,那么整个程序就会停止,退出程序的执行。
如果你定义一个函数有返回类型,可以想下面那样调用:
int func()
{
int value;
……
……
……
return value;
}
int main()
{
int intvalue;
intvalue=func();
……
……
teturn 0;
}


return语句后面具体是什么内容,这就要具体情况具体分析了:
(1) 在返回类型是char的函数中,return后应该是char类型的值;
(2) 在返回类型是int的函数中,如果是要停止函数的调用,最好应该为0;其他的按照你的目的而定,只要是int 类型就行了
(3) 在返回类型是结构类型的函数中,return后应该是结构的一个实例对象。
总之,函数定义为什么样的返回类型,该函数中return后就应该是相应类型的值。

C语言学习三

二元一次方程解法

#include<stdio.h>
#include<math.h>
#define eps 1e-6
main()
{
    float a,b,c,d;
    printf("Please enter the coefficients a,b,c:");
    scanf("%f,%f,%f",&a,&b,&c);
    if(a==0)
    printf("It is not a quadratic equation!\n");
    else
    {
        d=sqrt(fabs(b*b-4*a*c));
        if(fabs(b*b-4*a*c)<eps)
        printf("x1 = x2 = %.2f\n",(-b+d)/2/a);
        else if(b*b-4*a*c>eps)
        printf("x1 = %.2f, x2 = %.2f\n",(-b+d)/2/a,(-b-d)/2/a);
        else
        printf("x1 = %.2f+%.2fi, x2 = %.2f-%.2fi\n",-b/2/a ,d/2/a ,-b/2/a ,-d/2/a);
    }
}

注意:在这个程序中,最好不要用pow函数

因为:pow是有精度损失的

          计算机没这么聪明,能判断出你的是int型pow,计算机全部当double处理了

pow(2,2) = 3.999999999
pow(2,2) + 0.05 = 4.0499999
然后强制转化就会成为4了

eg

for(i=1;i<=  (int)(pow(m,1.0/3)+0.05); i++)

附上第一次的麻烦代码:

#include<stdio.h>
#include<math.h>
#define   EPS 1e-6
#include "windows.h"
main()
{
    float a,b,c;
    float d;
    printf("Please enter the coefficients a,b,c:");
    scanf("%f,%f,%f",&a,&b,&c);
    d=sqrt(b*b-4*a*c);
    if(a==0)
    printf("It is not a quadratic equation!\n");
    else{
    if(b*b-4*a*c==0)
    printf("x1 = x2 = %.2f\n",(-b+d)/(2*a));
    else if(b*b-4*a*c>0)
    printf("x1 = %.2f, x2 = %.2f\n",(-b+d)/(2*a),(-b-d)/(2*a));
    else
    printf("x1 = %.2f+%.2fi, "  "x2 = %.2f-%.2fi\n",-b/(2*a),sqrt(fabs(b*b-4*a*c))/(2*a),-b/(2*a),sqrt(fabs(b*b-4*a*c))/(2*a));
         
    }


 

C语言学习二

1.

亲密数_1
2500年前数学大师毕达哥拉斯就发现,220与284两数之间存在着奇妙的联系:
220的真因数之和为:1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为:1+2+4+71+142=220
毕达哥拉斯把这样的数对称为相亲数。

相亲数,也称为亲密数,如果整数A的全部因子(包括1,不包括A本身)之和等于B,且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。
从键盘任意输入两个整数m和n,编程判断m和n是否是亲密数。若是亲密数,则输出“Yes!”,否则输出“No!”

程序运行示例1
Input m, n:
220,284↙
Yes!

程序运行示例2Input m, n:
224,280↙
No!

输入格式: "%d,%d"
输出格式:
输入提示信息:"Input m, n:\n"
输出提示信息:"Yes!\n"
              "No!\n"

 

#include<stdio.h>
judgeclose(a,b);
main()
{
    printf("Input m, n:\n");
    int m,n;
    scanf("%d,%d",&m,&n);
    if(judgeclose(m,n)==1)
    printf("Yes!\n");
    else
    printf("No!\n");
}
judgeclose(a,b)
{
    int i,j,k=0;
    int s[20]={0},t[20]={0},e[20]={0},f[20]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            t[k]=j;
            k++;
            }
        }
     for(i=1;i<=b;i++)
        for(j=2;j<b;j++)
        {
            if (i*j==b)
            {
            e[k]=i,f[k]=j;
            k++;
            }
        }
        int s1=0,s2=0;
    for(i=0;i<20;i++)
    {
        s1+=s[i]+t[i];
        s2+=e[i]+f[i];
    }
   s1=s1/2+1;
   s2=s2/2+1;
    if(s1==b&&s2==a)
        return 1;
    else return 0;
}

看我写的这串垃圾代码。。。

要是考试肯定半个小时构思+写肯定写不完。。。

再看看同一类型题大神的方法:

2.

链接)一个数对(x,y)是亲和数对,当且仅当 x 的非自身的因数之和等于 y,且 y 的非自身的因数之和等于 x。如果(x,y)是亲和数对,那么认为(y,x)是与之相同的亲和数对。若 A<=x<=B,则称亲和数对(x,y)在[A,B]范围内。现输入范围 A 和 B,求 [A,B] 内所有亲和数对个数。例如 [200,1200] 内有两个亲和数对 (220,284) 和 (1184,1210),因为 220 的非自身因数和 1+2+4+5+10+11+20+22+44+55+110=284,284 的非自身因数之和为 1+2+4+71+142=220。
解一:解法骨架是枚举 [A,B] 范围内所有 x,算出 x 的非自身正因数之和 y(y < x),若 y 的非自身因数之和为 x,则代表找到了一个亲和数对。于是得到了一个直观的朴素解法。
解二:但显然上述解法效率过低。为了避免重复计算,我们创建一个 res[x] 数组保存 x 的因子和。于是得到了比解一快得多的解法。
解三:但是上述解法仍然太慢。问题在哪里?容易知道,时间主要耗费在了计算因子上(% 和 / 是同一个CPU指令,耗费时间相同)。我们不妨换一种思维方式,枚举因子 i,并把因子 i 加到 res[i*j] 里面,当枚举结束时,res[x] 就是 x 的因子和。这个方法快在两个方面:(1)机器算乘法本来就比除法快;(2)没有多余的整除判断。于是我们得到了最快的解法,并且代码比上面两种解法更为简洁。下面的代码利用了全局变量默认为空,没有 memset(res, 0, sizeof res)。

#include <stdio.h>
int res[100000005];
int main() {
  int A, B, ans=0;
  scanf("%d%d", &A, &B);
  for(int i = 1; i <= B; ++i)
    for(int j = 2; i*j <= 2*B; ++j)
      res[i*j] += i;
  for(int x = A; x <= B; ++x)
    if(res[x] > x && res[res[x]] == x) ++ans;
  printf("%d\n", ans);
  return 0;
}

需要说明的是

(要运行这个程序,我们需要在C99并添加新的头文件或C++编译器下进行!)

于是差距就出现了:手动滑稽hhh

Plus:C++真的比C语言简便好多啊

From:Kai

3.

完全数
完全数(Perfect Number),又称完美数或完数,它是指这样的一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和,恰好等于它本身,即m的所有小于m的不同因子(包括1)加起来恰好等于m本身。注意:1没有真因子,所以1不是完全数。计算机已经证实在10300以下,没有奇数的完全数。例如,因为6 = 1 + 2 + 3,所以6是一个完全数。
从键盘任意输入一个整数m,编程判断m是否是完全数。若m是完全数,则输出“Yes!”,并同时打印出每一个完美数的全部因子,以验证这个数确实是一个完美数。若m不是完全数,则输出“No!”
程序运行示例1
Input m:
28↙
Yes!
1,2,4,7,14

程序运行示例2
Input m:
6↙
Yes!
1,2,3

程序运行示例3
Input m:
1↙
No!

输入信息提示:"Input m:\n"
输入格式: "%d"

输出格式: "%d"
输出因子时用逗号间隔,格式为:  ","
判断是完全数,输出信息提示:"Yes!\n"
判断不是完全数,输出信息提示: "No!\n"

//有了上一道题作为基础,这道题就显得很简单了//

#include<stdio.h>
judgetrue(a);
main()
{
    printf("Input m:\n");
    int m;
    scanf("%d",&m);
    judgetrue(m);
}
judgetrue(a)
{
    int i,j,k=0;
    int s[20]={0},t[20]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<=a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            t[k]=j;
            k++;
            }
        }
    int s1=0;
    for(i=0;i<20;i++)
    {
        s1+=s[i];
    }
    if(s1==a)
    {
        printf("Yes!\n");
        for(i=0;i<20;i++)
        {
            if(s[i]!=0)
           {
               printf("%d",s[i]);
               if(s[i+1]!=0)
                printf(",");

           }
        }

    }
    else
    printf("No!\n");
}

4.

五个水手在岛上发现一堆椰子,先由第1个水手把椰子分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。然后,第2个水手把剩下的4堆混合后重新分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。以后第3、4个水手依次按此方法处理。最后,第5个水手把剩下的椰子分为等量的5堆后,同样剩下1个给了猴子。请用迭代法编程计算并输出原来这堆椰子至少有多少个。
**输出格式要求:"y = %d\n"

#include "stdio.h"
int can(int k)
{
   int i;
   for (i=1;i<=5;i++)
   {
       if ((k-1)%5!=0||k<  5) return 0;
       k=(k-1)/5*4;
   }
   return 1;
}
int main()
{
   int ans=1;
   while (!can(ans)) ans++;
   printf("y = %d\n",ans);

   return 0;
}

5.求1000内的

#include<stdio.h>
#define m 1000
judgetrue(a);
main()
{
    int i;
    for(i=2;i<=m;i++)
    judgetrue(i);
}
judgetrue(a)
{
    int i,j,k=0;
    int s[100]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<=a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            k++;
            }
        }
    int s1=0;
    for(i=0;i<100;i++)
    {
        s1+=s[i];
    }
    if(s1==a)
    {
        printf("\n%5d\n",s1);
        for(i=0;i<20;i++)
        {
            if(s[i]!=0)
           {
               printf("%5d",s[i]);
           }
        }

    }
    else;
}

你可以发现:我每个程序都是在原程序的基础上进行修改而成的。

所以我把这些程序上传在了这个博客上,以备后事之需。

C语言练习一

1.

奥运参赛国出场次序:
输入奥运会参赛国国名,并按照字典序对其进行排序。
要求:参赛国数量不超过150个,每个国家的名字不超过9个字符。
提示:‘\0’占一个字符。

#include <string.h>
#include <stdio.h>
#define N 151
#define MAX_LEN 10
void SortString(char str[][MAX_LEN], int n);

int main()
{
    int i, n;
    char name[N][MAX_LEN];
    printf("How many countries?");
    scanf("%d",&n);
    getchar();
    printf("Input their names\n");

    for(i=0;i<n;i++)
        gets(name[i]);

    SortString(name, n);
    printf("Sorted results:\n");
    for(i=0;i<n;i++)
    {
        puts(name[i]);
    }
    return 0;

}

void SortString(char str[][MAX_LEN], int n)
{
    int i,j;
    char temp[MAX_LEN];

    for(i=0;i<n;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(strcmp(str[j],str[i])<0)
            {
                strcpy(temp,str[i]);
                strcpy(str[i],str[j]);
                strcpy(str[j],temp);
            }
        }
    }
}

2.

统计正整数中指定数字的个数
从键盘输入一个正整数number,求其中含有指定数字digit的个数。例如:从键盘输入正整数number=1222,若digit=2,则1223中含有 3个2,要求用函数实现。
函数原型为:int CountDigit(int number,int digit);

程序运行结果示例1:
Input m,n:
1222,2↙
3

程序运行结果示例2:
Input m,n:
1234,6↙
0

输入格式: "%d,%d"
输出格式:
输入提示信息:"Input m,n:\n"
输出格式:"%d\n"

#include<stdio.h>
int CountDigit(int number,int digit);
main()
{
    printf("Input m,n:\n");
    int m,n;
    scanf("%d,%d",&m,&n);
    printf("%d\n",CountDigit(m,n));
}
int CountDigit(int number,int digit)
{
    int c=0;
    while(number)
    {
        if(digit==number%10)
        {c++;
        number=number/10;
        }
    }
    return c;
}

3.冒泡程序

#include<stdio.h>
#define LEN 10
void bubble(int dat[], int length);
main( )
{
    int  data[LEN]={0}, i;
    for (i=0; i<= LEN-1; i++)
    {
        scanf("%d",&data[i]);
    }
    bubble(data,LEN);
    for(i=0; i<= LEN-1; i++)     
        {
            printf("%8d", data[i]);
        }
}
void bubble(int dat[], int length)
{
        int head, tail,round,i;
        int t;
        head = 0;
        tail = length - 1;
 
    for (round = head; round <= tail; round++)
        for (i = tail; i >= round+1; i--)
            if ( dat[i] < dat[i-1] )
            {
                t=dat[i];             
                dat[i]=dat[i-1];
                dat[i-1]=t;
            }
}

4.实验题

编写程序统计从键盘输入的一行文本中各个字母的个数。
输入以回车键结束。
不区分大小写,大写字母与相应的小写字母按照同一个字母看待。
要求输出按照各个字母出现的个数从大到小进行排序,出现的个数相同的,按照字母在字母表中的先后顺序进行排序。
***输入格式:调用getchar()函数依次输入每个字符
***输出格式:"%c(%c):%d\n"
例如输入以下文本:
Hello World
程序将输出:
L(l):3
O(o):2
D(d):1
E(e):1
H(h):1
R(r):1
W(w):1
A(a):0
B(b):0
C(c):0
F(f):0
G(g):0
I(i):0
J(j):0
K(k):0
M(m):0
N(n):0
P(p):0
Q(q):0
S(s):0
T(t):0
U(u):0
V(v):0
X(x):0
Y(y):0
Z(z):0

#include <stdio.h>
#include<stdlib.h>
void bubble_sort(int a[], int c[],int n);
int main(void)
{int i;
int c[27]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
 char j;
 char a;                                       
 int b[26]={0};                      
 int count[26]={0};
 while ((a = getchar()) != '\n')     
   {
   for (j='A';j<='Z';++j)               
       {
           if (a == j || a == j+32)
           {
               b[j-'A']++;count[j-'A']++;
           }
   
       }
   }
   bubble_sort(b,c,26);
   for (i=0;i<26;++i)
   {
        printf("%c(%c):%d\n",c[i]-32,c[i],b[i]);
           
   }
}
    
void bubble_sort(int a[],int c[], int n)
{
    int i, j, temp;
    for (j = 0; j < n - 1; j++)
        for (i = 0; i < n - 1 - j; i++)
        {
            if(a[i] < a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
                temp = c[i];
                c[i] = c[i + 1];
                c[i + 1] = temp;
            }
        }
}

这道题是我做过后觉得比较难的,可能算法并不是很简便,如果各位大神有什么好的方法请一定告诉我。