1.C语言课程设计

2.学生成绩记录薄 c语言 课程设计报告

c语言课程设计小结300字_c语言课程设计小结

2.1程序功能介绍

贪吃蛇游戏是一个经典小游戏,一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,同时记10分,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。

2.2程序整体设计说明

一个游戏要有开始部分,运行部分,结束部分(实际上开始部分与运行部分是一体的)。

2.2.1设计思路

这个程序的关键是表示蛇的图形以及蛇的移动。用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示。移动时必须从蛇头开始,所以蛇不能向相反方向移动,也就是蛇尾不能改作蛇头。如果不按任何键,蛇自行在当前方向上前移,当游戏者按了有效的方向键后,蛇头朝着指定的方向移动,一步移动一节身体,所以当按了有效的方向键后,先确定蛇头的位置,然后蛇身体随着蛇头移动,图形的实现是从蛇头的新位置开始画出蛇,这时由于没有庆平的原因,原来蛇的位置和新蛇的位置差一个单位,所以看起来社会多一节身体,所以将蛇的最后一节用背景色覆盖。食物的出现和消失也是画矩形块和覆盖矩形块

2.2.2数据结构设计及用法说明?

开始部分:

游戏是运行在图形模式下的,所以第一步一定是初始化图形模式,接着要有开始的界面,就像书有封面一样,我设置了一个游戏的标题画面,除了游戏标题画面我还设置了一个欢迎画面。标题画面以后,还要为游戏的运行部分作初始化,包括绘制游戏运行时的背景,对游戏某些重 要变量的初始化。

运行部分:

作为游戏的核心部分,这里包括的函数比较多,也就是模块比较多,首先让我模拟一下贪吃蛇的游戏模式:某个世界上突然出现一条蛇,它很短,它的运动神经异常,它没法停止自己的多动症在它的世界里就只有食物,它很饿,也很贪吃;同样在不明原因的情况下,食物从天而降,可惜的是没有落到嘴边;饥饿的主人公,不管它有没有毒,也不问食物的来历,径直向食物爬去;它吃到食物啦,它超出想象的同化能力让食物很快的成为自己身体的一部分,它的身子变长啦。当它吃到第一颗食物时,上帝有给它第二颗,于是它吃了第二颗,于是又变长了,于是又有第三颗它的身子是一直的加长,它不管自己过长身体的麻烦——转身不便,继续吃下去,现在它是直接把巴张大,好让食物有个绿色通道。但是在某天的下午,它咬到了自己,它才想起自己是一条毒蛇,于是晕死过去(不是毒死);又或者它往食物冲锋的时候,它失去控制,撞到了墙上。

第一轮循环:第一步,出现食物;第二步,蛇不停运动;第三步,检查蛇是撞到自己或墙壁;由第四步起游戏有两条支线(A、B):

A :第四步,蛇没有碰到自己或墙壁,蛇继续前进,绘制蛇的动作;第五步,判断蛇是否吃到食物,如果蛇吃到食物,身子变长,原来的食物消失;第六步,让玩家输入控制指令,让蛇在下一轮循环的第二步改变运动方向;第七步,第二轮循环的第一步,重复第一轮的步骤;

B:第四步,蛇碰到自己或墙壁,终止游戏。

结束部分:

游戏结束时,显示“GAME OVER”,已经是约定俗成的规律了,我的游戏也不例外。除了游戏结束画面外,我还设置了一个游戏退出画面,“善始善终”嘛。

有了上述的大致划分,我把整个程序划分成(13+2)个模块(其实就是函数)

2.2.3程序结构(流程图)

图2.1流程图

依据所需要处理的任务要求,规划输入数据和输出结果,决定存放数据的数据结构。

C语言中数据结构集中体现在数据类型上,因此在进行C语言程序设计时,应统筹规划程序中所使用的变量,数组,指针等,以及它们的类型等。这点是很重要的,如果在此期间选择不合适的变量或者数组,将来修改就十分困难。

现在分析一下贪吃蛇游戏中的元素,继而得出与它们对应的在程序中的描述:

蛇:

基本描述:长度,颜色,位置。

对应数据与数据类型:长度—虽然可以用坐标表示,但是这样的话,运算量将很大,所以换算成较大的单位—节数,以固定长度的每节描述;坐标--整型;颜色--整型; 位置--X,Y坐标。

增加的描述:蛇运动的方向,蛇的生命。

对应数据与数据类型:这些描述是为了与程序的按键的输入部分与判断游戏结束部分相联系而设的。方向只有四个方向:上下左右。可以设置与之对应的四个整型数:3、4、2、1。生命就只有两种情况:死或生,对应0或1。

食物:

基本描述:颜色,位置。

对应数据与数据类型:由于颜色设成固定的,所以不再讨论。位置—X、Y坐标。

增加的描述:食物的存在。

对应数据与数据类型:这是为了避免重复出现食物而设置的,与绘制食物的函数有联系。只有两个值:0或1(没有食物或有食物)

其他的元素:墙,由于它在显示上是作为背景而存在的,所以并没有什么说明实际的墙壁就是四条直线组成的边框,由坐标描述。

还需要的变量:键盘键入的键值(作为全局变量,整型);经常要使用的循环变量;自定义的填充图案;说明文字的字符数组;游戏的记分;游戏的速度(蛇的速度)。

图2.2蛇的不停运动的关键算法的流程图

2.2.4各模块的功能及程序说明

主要模块的实现思路和算法的流程图说明:

关键所在——蛇不停移动的Snakemove():

蛇的不停移动,就是蛇的下一节取代前一节的位置,在计算机中就是蛇下一节的位置坐标变成前一节的位置坐标。在上文中,已定义蛇的位置坐标为数组类型,一组坐标对应一节的位置,设有i+1节,由0到i节,第i节的坐标取第i-1节的坐标,第i-1节的坐标取第i-2节的坐标直到第1节取第0节的坐标。而第0节的坐标,即蛇头的坐标要往某个方向变化,变化量为蛇每节的长度。蛇的这种坐标轮换需要循环语句使其继续下去。 ?

2.2.5程序结果

运行程序得到如下初始界面图:

图2.3程序结果图

用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示:

图2.4程序结果图

蛇没有碰到自己或墙壁,蛇继续前进:

图2.5程序结果图

游戏结束时,显示“GAME OVER”

图2.6程序结果图

2.3程序源代码及注释

#define N 200

#include <graphics.h>

#include <stdlib.h>

#include <dos.h>

#define LEFT 0x4b00

#define RIGHT 0x4d00

#define DOWN 0x5000

#define UP 0x4800

#define ESC 0x011b

int i,key;

int score=0;/*得分*/

int gamespeed=50000;/*游戏速度自己调整*/

struct Food{

int x;/*食物的横坐标*/

int y;/*食物的纵坐标*/

int yes;/*判断是否要出现食物的变量*/

}food;/*食物的结构体*/

struct Snake{

int x[N];

int y[N];

int node;/*蛇的节数*/

int direction;/*蛇移动方向*/

int life;/* 蛇的生命,0活着,1死亡*/

}snake;

void Init(void);/*图形驱动*/

void Close(void);/*图形结束*/

void DrawK(void);/*开始画面*/

void GameOver(void);/*结束游戏*/

void GamePlay(void);/*玩游戏具体过程*/

void PrScore(void);/*输出成绩*/

/*主函数*/

void main(void){

Init();/*图形驱动*/

DrawK();/*开始画面*/

GamePlay();/*玩游戏具体过程*/

Close();/*图形结束*/}

/*图形驱动*/

void Init(void){

int gd=DETECT,gm;

registerbgidriver(EGAVGA_driver);

initgraph(&gd,&gm,"c:\\program files\\winyes\\tc20h\\bgi");

cleardevice();}

/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/

void DrawK(void){

/*setbkcolor(LIGHTGREEN);*/

setcolor(11);

setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/

for(i=50;i<=600;i+=10)/*画围墙*/ ? {

rectangle(i,40,i+10,49); /*上边*/

rectangle(i,451,i+10,460);/*下边*/ ? }

for(i=40;i<=450;i+=10) ?{

rectangle(50,i,59,i+10); /*左边*/

rectangle(601,i,610,i+10);/*右边*/ }}

/*玩游戏具体过程*/

void GamePlay(void){

randomize();/*随机数发生器*/

food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/

snake.life=0;/*活着*/

snake.direction=1;/*方向往右*/

snake.x[0]=100;snake.y[0]=100;/*蛇头*/

snake.x[1]=110;snake.y[1]=100;

snake.node=2;/*节数*/

PrScore();/*输出得分*/

while(1)/*可以重复玩游戏,压ESC键结束*/ ? {

while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/ ?{

if(food.yes==1)/*需要出现新食物*/ {

food.x=rand()%400+60;

food.y=rand()%350+60;

while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

food.x++;

while(food.y%10!=0)

food.y++;

food.yes=0;/*画面上有食物了*/ }

if(food.yes==0)/*画面上有食物了就要显示*/ {

setcolor(GREEN);

rectangle(food.x,food.y,food.x+10,food.y-10); }

for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/ {

snake.x[i]=snake.x[i-1];

snake.y[i]=snake.y[i-1]; }

/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/

switch(snake.direction) {

case 1:snake.x[0]+=10;break;

case 2: snake.x[0]-=10;break;

case 3: snake.y[0]-=10;break;

case 4: snake.y[0]+=10;break; }

for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/ {

if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]) {

GameOver();/*显示失败*/

snake.life=1;

break; } }

if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||

snake.y[0]>455)/*蛇是否撞到墙壁*/ {

GameOver();/*本次游戏结束*/

snake.life=1; /*蛇死*/ }

if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/

break;

if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/ {

setcolor(0);/*把画面上的食物东西去掉*/

rectangle(food.x,food.y,food.x+10,food.y-10);

snake.x[snake.node]=-20;snake.y[snake.node]=-20;

/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/

snake.node++;/*蛇的身体长一节*/

food.yes=1;/*画面上需要出现新的食物*/

score+=10;

PrScore();/*输出新得分*/ }

setcolor(4);/*画出蛇*/

for(i=0;i<snake.node;i++)

rectangle(snake.x[i],snake.y[i],snake.x[i]+10,

snake.y[i]-10);

delay(gamespeed);

setcolor(0);/*用黑色去除蛇的的最后一节*/

rectangle(snake.x[snake.node-1],snake.y[snake.node-1],

snake.x[snake.node-1]+10,snake.y[snake.node-1]-10); } ?/*endwhile(!kbhit)*/

if(snake.life==1)/*如果蛇死就跳出循环*/

break;

key=bioskey(0);/*接收按键*/

if(key==ESC)/*按ESC键退出*/

break;

else

if(key==UP&&snake.direction!=4)

/*判断是否往相反的方向移动*/

snake.direction=3;

else

if(key==RIGHT&&snake.direction!=2)

snake.direction=1;

else

if(key==LEFT&&snake.direction!=1)

snake.direction=2;

else

if(key==DOWN&&snake.direction!=3)

snake.direction=4;

}/*endwhile(1)*/}

/*游戏结束*/

void GameOver(void){

cleardevice();?

PrScore();

setcolor(RED);

settextstyle(0,0,4);

outtextxy(200,200,"GAME OVER");

getch();}

/*输出成绩*/

void PrScore(void){

char str[10];

setfillstyle(SOLID_FILL,YELLOW);

bar(50,15,220,35);

setcolor(6);

settextstyle(0,0,2);

sprintf(str,"score:%d",score);

outtextxy(55,20,str);}

/*图形结束*/

void Close(void){

getch();

closegraph();

}

C语言课程设计

摘要:又称概要、内容提要。摘要是以提供文献内容梗概为目的,不加评论和补充解释,简明、确切地记述文献重要内容的短文。其基本要素包括研究目的、方法、结果和结论。具体地讲就是研究工作的主要对象和范围,用的手段和方法,得出的结果和重要的结论,有时也包括具有情报价值的其它重要的信息。

C语言课程设计,应该主要根据你的设计内容,简要地提炼出设计的背景,功能,意义等。最后给出关键字。下面是正文。

例如:

摘要(标题居中)

近年来随着计算机在社会领域的不断发展,程序设计 。。。。。C语言。。。。(这里讲你做的东西的背景。)

本课程设计完成了什么。。。。(功能)

其意义是。。。。(意义)

关键词: C语言,其他

参考资料:

://baike.baidu/view/1238.htm

学生成绩记录薄 c语言 课程设计报告

/******头文件(.h)***********/

#include "stdio.h" /*I/O函数*/

#include "stdlib.h" /*标准库函数*/

#include "string.h"/*字符串函数*/

#include "ctype.h" /*字符操作函数*/

#include "conio.h" /*控制台输入输出函数 */

#define M 50 /*定义常数表示记录数*/

typedef struct /*定义数据结构*/

{

char name[20]; /*姓名*/

char units[30]; /*单位*/

char tele[20]; /*电话*/

char m_ph[20]; //手机

char rela[20]; //关系

char email[50]; //邮箱

char qq[20]; //qq

}ADDRESS;

/******以下是函数原型*******/

int enter(ADDRESS t[]); /*输入记录*/

void list(ADDRESS t[],int n); /*显示记录*/

void search(ADDRESS t[],int n); /*按姓名查找显示记录*/

int Delete(ADDRESS t[],int n); /*删除记录*/

int add(ADDRESS t[],int n); /*插入记录*/

void se(ADDRESS t[],int n); /*记录保存为文件*/

int load(ADDRESS t[]); /*从文件中读记录*/

void display(ADDRESS t[]); /*按序号查找显示记录*/

void sort(ADDRESS t[],int n); /*按姓名排序*/

void qseek(ADDRESS t[],int n); /*快速查找记录*/

void print(ADDRESS temp); /*显示单条记录*/

int find(ADDRESS t[],int n,char *s) ; /*查找函数*/

int menu_select(); /*主菜单函数*/

/******主函数开始*******/

main()

{

system("color 37");//背景色为浅绿,前景色为白色

printf(" 欢迎使用通讯录管理系统\n");//欢迎界面

int i;

ADDRESS adr[M]; /*定义结构体数组*/

int length; /*保存记录长度*/

for(;;)/*无限循环*/

{

switch(menu_select()) /*调用主菜单函数,返回值整数作开关语句的条件*/

{

case 0:length=enter(adr);break;/*输入记录*/

case 1:list(adr,length);break; /*显示全部记录*/

case 2:search(adr,length);break; /*查找记录*/

case 3:length=Delete(adr,length);break; /*删除记录*/

case 4:length=add(adr,length); break; /*插入记录*/

case 5:se(adr,length);break; /*保存文件*/

case 6:length=load(adr); break; /*读文件*/

case 7:display(adr);break; /*按序号显示记录*/

case 8:sort(adr,length);break; /*按姓名排序*/

case 9:qseek(adr,length);break; /*快速查找记录*/

case 10:exit(0); /*如返回值为10则程序结束*/

}

}

}

/*菜单函数,函数返回值为整数,代表所选的菜单项*/

int menu_select()

{

char s[80];

int c;

printf("按任意键进入菜单......\n");/*提示按任意键继续*/

getch(); /*读入任意字符*/

system("cls"); /*清屏*/

printf(" ********************菜单***********************\n\n");

printf(" 0. 输入记录\n");

printf(" 1. 显示所有记录\n");

printf(" 2. 按姓名查找记录\n");

printf(" 3. 删除记录\n");

printf(" 4. 添加记录\n");

printf(" 5. 保存文件\n");

printf(" 6. 载入文件\n");

printf(" 7. 按序号显示记录\n");

printf(" 8. 记录排序\n");

printf(" 9. 查找记录\n");

printf(" 10. 退出\n");

printf(" ***********************************************\n");

do

{

printf("\n 请输入选项(0~10):"); /*提示输入选项*/

scanf("%d",&c);/*输入选择项*/

fflush(stdin);

}while(c<0 || c>10);/*选择项不在0~10之间重输*/

return c; /*返回选择项,主程序根据该数调用相应的函数*/

}

/***输入记录,形参为结构体数组,函数值返回类型为整型表示记录长度*/

int enter(ADDRESS t[])

{

int i,n;

char num[30];

system("cls"); /*清屏*/

int flag=1;

for(;;)

{

flag = 1;

system("cls"); /*清屏*/

printf("\n请输入记录数:\n"); /*提示信息*/

scanf("%s", &num); /*输入记录数*/

fflush(stdin);

for(int nima = 0; num[nima]; nima++)

{

if (num[nima] < 48 || num[nima] > 57)

{

flag = 0;

break;

}

}

if(flag==1)

break;

}

n=atoi(num);

printf("请输入记录:\n"); /*提示输入记录*/

printf("姓名 单位 电话 手机 关系 邮箱 QQ\n");

printf("--------------------------------------------------------------------------\n");

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

{

scanf("%s%s%s%s%s%s%s",t[i].name,t[i].units,t[i].tele,t[i].m_ph,t[i].rela,t[i].email,t[i].qq); /*输入记录*/

fflush(stdin);

for(int k=0;k<=19;k++)

{

if((t[i].tele[k]>='a' && t[i].tele[k]<='z' )|| (t[i].tele[k]>='A' && t[i].tele[k]<='Z'))

{

printf("电话输入错误!请重新输入联系人信息\n");

i--;

break;

}

if((t[i].m_ph[k]>='a' && t[i].m_ph[k]<='z' )|| (t[i].m_ph[k]>='A' && t[i].m_ph[k]<='Z'))

{

printf("手机输入错误!请重新输入联系人信息\n");

i--;

break;

}

if((t[i].qq[k]>='a' && t[i].qq[k]<='z' )|| (t[i].qq[k]>='A' && t[i].qq[k]<='Z'))

{

printf("QQ输入错误!请重新输入联系人信息\n");

i--;

break;

}

}

printf("--------------------------------------------------------------------------\n");

}

return n; /*返回记录条数*/

}

/*显示记录,参数为记录数组和记录条数*/

void list(ADDRESS t[],int n)

{

int i;

system("cls"); /*清屏*/

printf("\n\n************************************************************************\n");

printf("姓名 单位 电话 手机 关系 邮箱 QQ\n");

printf("--------------------------------------------------------------------------\n");

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

printf("%-10s%-14s%-12s%-12s%-10s%-12s%-14s\n",t[i].name,t[i].units,t[i].tele,t[i].m_ph,t[i].rela,t[i].email,t[i].qq);

if((i+1)%10==0) /*判断输出是否达到10条记录*/

{

printf("按任意键显示下一页\n"); /*提示信息*/

getch(); /*按任意键继续*/

}

printf("*********************************结束***********************************\n");

}

/*查找记录*/

void search(ADDRESS t[],int n)

{

char s[20]; /*保存待查找姓名字符串*/

int i; /*保存查找到结点的序号*/

system("cls"); /*清屏*/

printf("请输入待查找姓名:\n");

scanf("%s",s); /*输入待查找姓名*/

i=find(t,n,s); /*调用find函数,得到一个整数*/

if(i>n-1) /*如果整数i值大于n-1,说明没找到*/

{

printf("未找到!!!\n");

getch();

}

else

print(t[i]); /*找到,调用显示函数显示记录*/

}

/*显示指定的一条记录*/

void print(ADDRESS temp)

{

system("cls"); /*清屏*/

printf("\n\n************************************************************************\n");

printf("姓名 单位 电话 手机 关系 邮箱 QQ\n");

printf("--------------------------------------------------------------------------\n");

printf("%-10s%-14s%-12s%-12s%-10s%-12s%-14s\n",temp.name,temp.units,temp.tele,temp.m_ph,temp.rela,temp.email,temp.qq);

printf("*********************************结束***********************************\n");

getchar();

}

/*查找函数,参数为记录数组和记录条数以及姓名s */

int find(ADDRESS t[],int n,char *s)

{

int i;

system("cls"); /*清屏*/

for(i=0;i<n;i++)/*从第一条记录开始,直到最后一条*/

{

if(strcmp(s,t[i].name)==0) /*记录中的姓名和待比较的姓名是否相等*/

return i; /*相等,则返回该记录的下标号,程序提前结结束*/

}

return i; /*返回i值*/

getch();

}

/*删除函数,参数为记录数组和记录条数*/

int Delete(ADDRESS t[],int n)

{

char s[20]; /*要删除记录的姓名*/

char ch;

int i,j;

system("cls"); /*清屏*/

printf("请输入待删除的姓名:\n"); /*提示信息*/

scanf("%s",s);/*输入姓名*/

i=find(t,n,s); /*调用find函数*/

if(i>n-1) /*如果i>n-1超过了数组的长度*/

printf("未找到!!!\n"); /*显示没找到要删除的记录*/

else

{

print(t[i]); /*调用输出函数显示该条记录信息*/

printf("确定删除?(Y/N)\n"); /*确认是否要删除*/

scanf("%c",&ch); /*输入一个整数0或1*/

if(ch=='y' || ch=='Y') /*如果确认删除输入y*/

{

for(j=i+1;j<n;j++) /*删除该记录,实际后续记录前移*/

{

strcpy(t[j-1].name,t[j].name); /*将后一条记录的姓名拷贝到前一条*/

strcpy(t[j-1].units,t[j].units); /*将后一条记录的单位拷贝到前一条*/

strcpy(t[j-1].tele,t[j].tele); /*将后一条记录的电话拷贝到前一条*/

strcpy(t[j-1].m_ph,t[j].m_ph); /*将后一条记录的手机拷贝到前一条*/

strcpy(t[j-1].rela,t[j].rela); /*将后一条记录的关系拷贝到前一条*/

strcpy(t[j-1].email,t[j].email); /*将后一条记录的邮箱拷贝到前一条*/

strcpy(t[j-1].qq,t[j].qq); /*将后一条记录的qq拷贝到前一条*/

}

printf("删除成功!\n");

n--; /*记录数减1*/

}

}

getch();

return n; /*返回记录数*/

}

/*插入记录函数,参数为结构体数组和记录数*/

int add(ADDRESS t[],int n)/*插入函数,参数为结构体数组和记录数*/

{

ADDRESS temp; /*新插入记录信息*/

int i,j,flag;

char s[30]; /*确定插入在哪个记录之前*/

system("cls"); /*清屏*/

printf("请输入记录:\n");

printf("************************************************************************\n");

printf("姓名 单位 电话 手机 关系 邮箱 QQ\n");

printf("--------------------------------------------------------------------------\n");

scanf("%s%s%s%s%s%s%s",temp.name,temp.units,temp.tele,temp.m_ph,temp.rela,temp.email,temp.qq); /*输入插入信息*/

fflush(stdin);

printf("请输入插入位置的姓名: \n");

scanf("%s",s); /*输入插入位置的姓名*/

i=find(t,n,s); /*调用find,确定插入位置*/

for(j=n-1;j>=i;j--) /*从最后一个结点开始向后移动一条*/

{

strcpy(t[j+1].name,t[j].name); /*当前记录的姓名拷贝到后一条*/

strcpy(t[j+1].units,t[j].units); /*当前记录的单位拷贝到后一条*/

strcpy(t[j+1].tele,t[j].tele); /*当前记录的电话拷贝到后一条*/

strcpy(t[j+1].m_ph,t[j].m_ph); /*当前记录的手机拷贝到后一条*/

strcpy(t[j+1].rela,t[j].rela); /*当前记录的关系拷贝到后一条*/

strcpy(t[j+1].email,t[j].email); /*当前记录的邮箱拷贝到后一条*/

strcpy(t[j+1].qq,t[j].qq); /*当前记录的qq拷贝到后一条*/

}

strcpy(t[i].name,temp.name); /*将新插入记录的姓名拷贝到第i个位置*/

strcpy(t[i].units,temp.units); /*将新插入记录的单位拷贝到第i个位置*/

strcpy(t[i].tele,temp.tele); /*将新插入记录的电话拷贝到第i个位置*/

strcpy(t[i].m_ph,temp.m_ph); /*将新插入记录的手机拷贝到第i个位置*/

strcpy(t[i].rela,temp.rela); /*将新插入记录的关系拷贝到第i个位置*/

strcpy(t[i].email,temp.email); /*将新插入记录的邮箱拷贝到第i个位置*/

strcpy(t[i].qq,temp.qq); /*将新插入记录的qq拷贝到第i个位置*/

n++; /*记录数加1*/

printf("添加成功!!!\n");

getch();

return n; /*返回记录数*/

}

/*保存函数,参数为结构体数组和记录数*/

void se(ADDRESS t[],int n)

{

int i;

char outfile[30];

FILE *fp; /*指向文件的指针*/

system("cls"); /*清屏*/

printf("请输入待保存的文件名:\n");

scanf("%s",outfile);

if((fp=fopen(outfile,"wb"))==NULL) /*打开文件,并判断打开是否正常*/

{

printf("无法打开文件!\n");/*无法打开*/

exit(1); /*退出*/

}

printf("\n保存文件...\n"); /*输出提示信息*/

fprintf(fp,"%d",n); /*将记录数写入文件*/

fprintf(fp,"\r\n"); /*将换行符号写入文件*/

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

{

fprintf(fp,"%-10s%-14s%-12s%-12s%-10s%-12s%-14s\n",t[i].name,t[i].units,t[i].tele,t[i].m_ph,t[i].rela,t[i].email,t[i].qq);/*格式写入记录*/

fprintf(fp,"\r\n"); /*将换行符号写入文件*/

}

fclose(fp);/*关闭文件*/

printf("****保存成功!****\n"); /*显示保存成功*/

getch();

}

/*载入函数,参数为结构体数组*/

int load(ADDRESS t[])

{

int i,n;

char outfile[30];

FILE *fp; /*指向文件的指针*/

system("cls"); /*清屏*/

printf("请输入待载入的文件名:\n");

scanf("%s",outfile);

if((fp=fopen(outfile,"rb"))==NULL)/*打开文件*/

{

printf("无法打开文件!\n"); /*不能打开*/

exit(1); /*退出*/

}

fscanf(fp,"%d",&n); /*读入记录数*/

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

fscanf(fp,"%10s%14s%12s%12s%10s%12s%14s",t[i].name,t[i].units,t[i].tele,

t[i].m_ph,t[i].rela,t[i].email,t[i].qq); /*按格式读入记录*/

fclose(fp); /*关闭文件*/

printf("从文件读入数据成功!!!\n"); /*显示保存成功*/

getch();

return n; /*返回记录数*/

}

/*按序号显示记录函数*/

void display(ADDRESS t[])

{

int id,n;

char outfile[30];

FILE *fp; /*指向文件的指针*/

system("cls"); /*清屏*/

printf("请输入待载入的文件名:");

scanf("%s",outfile);

if((fp=fopen(outfile,"rb"))==NULL) /*打开文件*/

{

printf("无法打开文件!\n"); /*不能打开文件*/

exit(1); /*退出*/

}

printf("请输入记录序号:\n"); /*显示信息*/

scanf("%d",&id); /*输入序号*/

fscanf(fp,"%d",&n); /*从文件读入记录数*/

if(id>=0&&id<n) /*判断序号是否在记录范围内*/

{

fseek(fp,(id-1)*sizeof(ADDRESS),1); /*移动文件指针到该记录位置*/

print(t[id]); /*调用输出函数显示该记录*/

printf("\r\n");

}

else

{

printf(" %d号记录不存在!!!\n ",id); /*如果序号不合理显示信息*/

getch();

}

fclose(fp); /*关闭文件*/

}

/*排序函数,参数为结构体数组和记录数*/

void sort(ADDRESS t[],int n)

{

int i,j,flag;

system("cls"); /*清屏*/

ADDRESS temp; /*临时变量做交换数据用*/

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

{

flag=0; /*设标志判断是否发生过交换*/

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

if((strcmp(t[j].name,t[j+1].name))>0) /*比较大小*/

{

flag=1;

strcpy(temp.name,t[j].name); /*交换记录*/

strcpy(temp.units,t[j].units);

strcpy(temp.tele,t[j].tele);

strcpy(temp.m_ph,t[j].m_ph);

strcpy(temp.rela,t[j].rela);

strcpy(temp.email,t[j].email);

strcpy(temp.qq,t[j].qq);

strcpy(t[j].name,t[j+1].name);

strcpy(t[j].units,t[j+1].units);

strcpy(t[j].tele,t[j+1].tele);

strcpy(t[j].m_ph,t[j+1].m_ph);

strcpy(t[j].rela,t[j+1].rela);

strcpy(t[j].email,t[j+1].email);

strcpy(t[j].qq,t[j+1].qq);

strcpy(t[j+1].name,temp.name);

strcpy(t[j+1].units,temp.units);

strcpy(t[j+1].tele,temp.tele);

strcpy(t[j+1].m_ph,temp.m_ph);

strcpy(t[j+1].rela,temp.rela);

strcpy(t[j+1].email,temp.email);

strcpy(t[j+1].qq,temp.qq);

}

if(flag==0)break; /*如果标志为0,说明没有发生过交换循环结束*/

}

printf("排序成功!!!\n"); /*显示排序成功*/

}

/*快速查找,参数为结构体数组和记录数*/

void qseek(ADDRESS t[],int n)

{

char s[20];

int l,r,m;

system("cls"); /*清屏*/

printf("\n请在查找前排序!\n"); /*提示确认在查找之前,记录是否已排序*/

printf("请输入待查找的姓名:\n"); /*提示输入*/

scanf("%s",s); /*输入待查找的姓名*/

l=0;r=n-1; /*设置左边界与右边界的初值*/

while(l<=r) /*当左边界<=右边界时*/

{

m=(l+r)/2; /*计算中间位置*/

if(strcmp(t[m].name,s)==0) /*与中间结点姓名字段做比较判是否相等*/

{

print(t[m]); /*如果相等,则调用print函数显示记录信息*/

return ; /*返回*/

}

if(strcmp(t[m].name,s)<0) /*如果中间结点小*/

l=m+1; /*修改左边界*/

else

r=m-1; /*否则,中间结点大,修改右边界*/

}

if(l>r) /*如果左边界大于右边界时*/

printf("未找到!\n"); /*显示没找到*/

getch();

}

C语言程序设计报告

课题名称:学生成绩管理

1 系统概述:

本程序为一个学生成绩管理系统,对学生的成绩进行管理,学生的信息包括学号,姓名,学期,三门课程的成绩,输入这些信息,本程序可以自动计算总成绩,可以按高分到低分进行排名,并对输入信息的人数进行汇总.

2 数据结构设计:

(1)结构体;

(2)数组的设计:运用指针代替数组,使用指针来建立线性表,使程序更加简洁,可读性更强.

3 各函数的设计:

函数原型:void InitList(SqLinkList &L);

功能: 创建一个空的线性链表;

入口参数:L为要创建的线性链表;

出口参数:创建链表的L.head为空,L.length为0;

返回值: 无;

函数原型:void EmptyLinkList(SqLinkList &L);

功能: 清空整个线性链表;

入口参数:L为要清空的链表名称;

出口参数:若清空成功则链表长度L.length为0;

返回值: 无;

函数原型:int ScanE(ElemType &e);

功能: 输入学生信息;

入口参数:e为要输入信息的学生名称;

出口参数:e.num保存学号,e.name保存姓名,e.team保存所在学期,e.s1,e.s2,e.s3分别保存三门课程的成绩;

返回值: 输入合法返回1,否则返回0;

错误处理:若学号、姓名等输入不合法会有提示及重输;

函数原型:Status SqLinkListAppend(SqLinkList &L,ElemType e);

功能: 追加一个结点到线性链表中;

入口参数:e为所追加的结点名称,L为e所追加到的线性链表的名称;

出口参数:若追加成功,则e为头结点,链表长度L.length增1;

返回值: 若追加成功返回1;

函数原型:Link SearchNode(SqLinkList L,int NUM);

功能: 查找学号为NUM的学生;

入口参数:查找的链表名称L,学号NUM;

出口参数:若找到结点指针p指向该结点,否则指向空结点;

返回值: 结点指针p;

函数原型:void SearchTeam(SqLinkList L,int team);

功能: 查找学期为team的所有记录并输出其信息;

入口参数:查找的链表名称L,要查找的学期team;

出口参数:无;

返回值: 无;

函数原型:void SearchUnpass(SqLinkList L,float s1,float s2,float s3);

功能: 查找所有有挂科记录的学生并输出其信息;

入口参数:查找的链表名称L,要查找的各门学科成绩s1,s2,s3;

出口参数:无;

返回值: 无;

函数原型:void SqLinkListSearch(SqLinkList L);

功能: 对链表进行分类查找;

入口参数:要查找的链表名称L;

出口参数:无;

返回值: 无;

函数原型: void inputData(SqLinkList &L);

功能: 输入数据,并追加一个结点;

入口参数: L为要追加结点的链表名称;

出口参数: 无;

返回值: 无;

函数原型:void SqLinkListTrerse(SqLinkList L);

功能: 输出链表中所有学生成绩列表;

入口参数:L为要输出信息的链表名称;

出口参数:无;

返回值: 无;

函数原型:void PrintE(ElemType e);

功能: 输出一个结点的所有信息;

入口参数:要输出的结点名称e;

出口参数:无;

返回值: 无;

4 使用程序的说明:

本程序为一个学生成绩管理系统。对学生的成绩信息进行管理,学生的信息包括学号、姓名、学期、三门课程的成绩、平均成绩、名次。本管理系统实现学生的学号、姓名、学期、每门课程的成绩的录入,并自动按平均分排名,使用时按屏幕上的提示,输入使用代码.如下图所示:

例如:输入代码数字”1”,程序执行”输入学生成绩或已存在的学生成绩进行修改”这条小程序.输入学生个人信息后,如下图所示:

如此分别输入相应的程序代码,就执行相应的程序段.

如下的程序是按学号进行成绩排名:

当输入”6”时,执行相应的程序,即汇总一共输入学生的人数:

5 总结和体会:

通过对C语言学习,尤其是这学期本班开展C语言双语教学,体会到学习难的同时,也真正了解到C语言作为一门高级的计算机语言的强大功能,特别是在当今实际生活,生产,办公,信息管理等方面的强大作用. 这次合作我们遇到了许多的困难。时间的紧迫,知识的不足,给我很大的压力。最终我还是还是完成了任务。团结就是力量是我这次最真切的感受。

6 程序代码:

void InitList(SqLinkList &L) {

// 构造一个空的线性表L;

L.head = 0; //头指针为空;

L.length = 0; //长度初始为0;

}

void EmptyLinkList(SqLinkList &L){

//入口参数为整个线性表的数据,功能为清空线性表;

Node *p;

if(!L.head)printf("系统中不存在记录。\n");

//头指针为空时没有学生录入;

else {

while (L.head){

//每个循环将下一结点赋值给头指针,并释放本结点空间,直至线性表清空;

p=L.head;

L.head=p->next;

free(p);

} //end while;

L.length=0; //长度为0;

printf("该管理系统学生信息已清空。\n");

}//end else;

}

int ScanE(ElemType &e){

//输入一个学生的成绩数据结点。返回0为无效结点数据,1为有效结点数据;

printf("\n学号:");

scanf("%d",&e.num);

if(e.num==0){

//学号为0输入不合法,重新输入;

printf("学号输入不合法.\n");

return 0;

}

printf("\n姓名:");

scanf("%s",&e.name);

printf("\n学期:");

scanf("%d",&e.team);

while(e.team>12){

//系统只记录小于12的学期数;

printf("输入的学期不能大于12,请重新输入:");

scanf("%d",&e.team);

}

printf("\n成绩A:");

scanf("%f",&e.s1);

printf("\n成绩B:");

scanf("%f",&e.s2);

printf("\n成绩C:");

scanf("%f",&e.s3);

return OK;

}

Status SqLinkListAppend(SqLinkList &L,ElemType e){

//追加一个结点到线性表中;

Node *p;

p=SearchNode(L,e.num);

//查找学号为e.num的记录并将其地址赋给指针p;

if (p==0){

//若不存在添加学号相同的结点,追加一个结点;

p=(Node *)malloc(sizeof(Node));

if (!p) return ERROR;

memcpy(&(p->data),&e,sizeof(ElemType));

p->next=L.head ;

L.head=p;

//追加的一个结点为首结点;

L.length++; //表长度加1;

}

else { //如果该学号记录已存在,则进行修改操作;

memcpy(&(p->data),&e,sizeof(ElemType));

printf("该学生记录已经存在,已完成修改操作。\n");

}

return OK;

}

Link SearchNode(SqLinkList L,int NUM){

//查找学生记录,该学生的学号为NUM;

Node *p;

p=L.head; //p先指在头结点;

while (p&& p->data.num !=NUM ) p=p->next;

//如果该学生的学号不为NUM则查找下一个结点;

return p;

}

void SearchTeam(SqLinkList L,int team){

//按学期查找并输出所有该学期存在的记录;

Node *p;

p=L.head;

int n,sum=0;

//sum记录该学期的学生总人数;

printf("请输入您要查询的学生的学期:");

scanf("%d",&n);

printf("\n学号 姓名 学期 成绩A 成绩B 成绩C 平均成绩\n");

while(p&&p->next){

//如果p结点和它的下一结点不为空,且该结点的学期等于要查找学期,则格式输出所有该学期学生信息;

if(p->data.team==n){

PrintE(p->data);

sum++;

//查找到一个该学期的学生记录计数加1;

}

p=p->next;

//转向下一结点;

} //end while;

if(p->data.team==n){

//如果p的下一结点为空,且本结点学期为n,则格式输出该结点信息;

sum++;

PrintE(p->data);

}

if(sum==0)printf("没有这学期的记录。\n");

if(sum)printf("该学期共有%d人的记录.\n",sum);

}

void SearchUnpass(SqLinkList L,float s1,float s2,float s3){

//查找并输出有挂科的学生信息;

Node *p;

p=L.head;

int sum=0;

//sum计数挂科总人数,初始为0;

printf("以下是有一门以上不及格科目的学生的成绩:\n");

printf("\n学号 姓名 学期 成绩A 成绩B 成绩C 平均成绩\n");

while(p&&p->next){

//如果p及其下一结点为真,且该结点有一门以上科目分数低于60则输出该结点成绩并使sum计数加1;

if((p->data.s1<60)||(p->data.s2<60)||(p->data.s3<60))

{

PrintE(p->data);

sum++;

} //end if;

p=p->next;

//转到下一结点;

} //end while;

if((p->data.s1<60)||(p->data.s2<60)||(p->data.s3<60)){

//查看最后一个结点,若有挂科,sum加1并格式输出结点信息;

sum++;

PrintE(p->data);

}

if(sum==0)printf("没有不及格的记录。\n");

if(sum)printf("共有%d人的挂科记录.\n",sum);

}

void SqLinkListSearch(SqLinkList L){

//分类查找学生记录;

Node *p;

p=L.head;

int n,reg; //reg为查询方式的指令;

printf("1--按学号查询\n2--按学期查询\n3--挂科学生信息列表\n");

printf("请您输入查询方式:");

scanf("%d",&reg);

if(L.length){

if(reg>3)printf("对不起没有您要求的选项。\n");

//若reg>3则输入不合法;

else if(reg==1){

//reg==1按学号查询;

printf("请输入您要查询的学生的学号:");

scanf("%d",&n);

while(p&&p->next&& p->data.num !=n) p=p->next;

//当p和他下一结点为真时且结点数据不为要查找数据时转向下一结点;

if(p->data.num==n){

//找到所要查询结点,格式输出;

printf("\n学号 姓名 学期 成绩A 成绩B 成绩C 平均成绩\n");

PrintE(p->data);

}

else printf("没有您要查找的学号。\n");

} //end reg==1 if ;

else if(reg==2)SearchTeam(L,p->data.team);

//reg==2,调用SearchTeam函数按学期查询并输出;

else if(reg==3)SearchUnpass(L,p->data.s1,p->data.s2,p->data.s3);

//reg==3,调用SearchUnpass函数,输出全部有挂科记录的学生信息;

}//end if;

else printf("系统中无记录.\n");

}

void inputData(SqLinkList &L){

//请求输入学生成绩,则追加一个结点并输入;

ElemType e;

if (ScanE(e)) SqLinkListAppend(L,e); //输入数据,追加一个结点;

}

void SqLinkListTrerse(SqLinkList L){

//所有学生信息列表输出;

Node *p;

char c;

p=L.head;

if(p) //非空表;

{

printf("\n学号 姓名 学期 成绩A 成绩B 成绩C 平均成绩\n");

for (p=L.head ;p;p=p->next )PrintE(p->data);

//从第一个结点开始输出所有信息直到结点为空;

}

else printf("系统中无记录。\n");

//空表;

c=getchar();

}

void PrintE(ElemType e){

//输出各科成绩和平均成绩;

printf("%d\t%s\t%d\t%f\t%f\t%f\t%f\n",e.num,e.name,e.team,e.s1,e.s2,e.s3,(e.s1+e.s2+e.s3)/3);

//格式输出学生的学号、姓名、学期、A、B、C三门成绩以及平均成绩;

}