加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

《C语言程序设计》上机实验八 参考答案

(2010-06-14 10:45:57)
标签:

教育

// C语言程序设计实验与习题指导

// 实验八 结构体、共用体、枚举类型
// P52 二
// 1) 编写程序:输入某个日期的年月日,计算并输出第二天的年月日,以及它在该年中是第几天。掌握结构体变量的定义与使用。要求:用结构体类型变量存放年月日:考虑闰年的情况。

#include <stdio.h>//包含头文件,主要是输入输出函数

struct date//定义日期类型结构体
{
 int yy,mm,dd;//分别定义年-yy、月-mm、日-dd
};

void main() //空类型主函数
{
 struct date day;//定义日期变量-day
 int i,flag=0,days=0; //定义循环变量-i,闰年标志-flg,某日在该年中第几天-days

 int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//非闰年时每个月天数,为保持月份数与数组下标数一致,数组长度定义为13,第0个数组元素不用,用month[1]表示第一月天数,month[2]表示第二月天数...以此类推

 do{
  printf("Please input a date(year month day):\n");//提示 请输入一个日期,包括年月日
  scanf("%d%d%d",&day.yy,&day.mm,&day.dd);//输入某一日期的年、月、日
  
  if(((day.yy%4==0)&&(day.yy%100!=0))||(day.yy%400==0)) //某年如果能被4整除并且不能被100整除或者能被400整除,则为闰年
   flag=1;//闰年标记置为1,表示该年为闰年;否则保持为初始设置的0,表示该年不为闰年
  else
   flag=0;//否则闰年标记置为0
  if(flag)//如果该年为闰年
   month[2]=29;//第二月份天数为29天

 }while(day.yy<0||day.mm<1||day.mm>12||day.dd<1||(day.mm!=2&&day.dd>month[day.mm])||(day.mm==2&&flag==0&&day.dd>28)||(day.mm==2&&flag==1&&day.dd>29));//要求输入的数据满足一定的条件,那就是年份大于0,月份在1~12之间,日期不超过该月最大天数且大于0

 //计算第二天的日期

 day.dd+=1;//首先将日子加一天
 if(day.dd>month[day.mm])//如果增加后的日子大于该月最大天数
 {
  day.dd=1;//该月天数归一
  day.mm+=1;//月份加一
 }
 if(day.mm>12)//如果月份大于12
 {
  day.mm=1;//月份归一
  day.yy+=1;//年份加一
 }

 printf("\n\nThe next day is %d-%d-%d.\n\n",day.yy,day.mm,day.dd);//输出第二天的日期

 if(((day.yy%4==0)&&(day.yy%100!=0))||(day.yy%400==0)) //某年如果能被4整除并且不能被100整除或者能被400整除,则为闰年
  flag=1;//闰年标记置为1,表示该年为闰年;否则保持为初始设置的0,表示该年不为闰年
 else
  flag=0;//否则闰年标记置为0
 if(flag)//如果该年为闰年
  month[2]=29;//第二月份天数为29天

 for(i=1;i<day.mm;i++)//计算改日是该年中第几天时,首先通过循环,将该日期前所有月份天数加起来
  days+=month[i];//依次加上该日期前所有月份天数
 days+=day.dd;//再加上该日子

 printf("The next day %d-%d-%d is the %d-th day of the year.\n\n",day.yy,day.mm,day.dd,days);//输出该日期是该年中的第几天
}

// 2)编写程序:有10个学生,每个学生的数据包括学号、姓名、3门课的成绩,从键盘输入这10个学生的数据,要求输出三门课程的
// 总平均成绩,并按总分从高到低输出所有学生的各数据项(学号、姓名、3门课的成绩及平均分)。掌握结构体数组的定义、使用,
// 学会使用结构体数组作函数参数,复习函数的定义、调用及排序算法。要求;用input函数输入10个学生的数据;用average函数求
// 三门课程的总平均成绩;用sort函数按总分高低进行排序;所有的数据输出都在主函数中进行。
#include <stdio.h>
#define SN 3 //学生数 10
#define CN 3  //课程数 3

//定义学生结构体
struct student
{
 long Num;//学号
 char Name[10];//姓名
 double Score[CN];//CN门课的成绩
 double AveSc;//CN门课的平均成绩
};

//输入10个学生的数据
void input(struct student *stu)
{
 int i,j;
 double sCN;

 printf("请输入%d个学生的学号、姓名、%d门课的成绩:\n\n",SN,CN);
 for(i=0;i<SN;i++)
 {
  sCN=0.0;
  scanf("%ld%s",&stu[i].Num,stu[i].Name);
  for(j=0;j<CN;j++)
  {
   scanf("%lf",&stu[i].Score[j]);
   sCN+=stu[i].Score[j];
  }
  stu[i].AveSc=sCN/CN;
 }
}

//求三门课程的总平均成绩
void average(struct student *stu,double *ave,double *ave3)
{
 int i,j;
 double sum[CN],s3=0.0;

 for(i=0;i<CN;i++)
 {
  sum[i]=0.0;
  for(j=0;j<SN;j++)
  {
   sum[i]+=stu[j].Score[i];
   s3+=stu[j].Score[i];
  }
  ave[i]=sum[i]/SN;
 }
 *ave3=s3/(SN*CN); 
}

//按总分高低进行排序,与按平均分高低进行排序等价
void sort(struct student *stu)
{
 int i,j,k;
 struct student st;

 for(i=0;i<SN-1;i++)
 {
  k=i;
  for(j=i+1;j<SN;j++)
  {
   if(stu[j].AveSc>stu[k].AveSc)
    k=j;
  }

  if(k!=i)
  {
   st=stu[i];
   stu[i]=stu[k];
   stu[k]=st;
  }
 }
}

void main()
{
 int i,j,k;
 double ave[CN],aveT;
 struct student stu[SN];

 input(stu);
 average(stu,ave,&aveT);
 sort(stu);

 printf("学生的学号 姓名 三门课成绩 三门课平均成绩 如下:\n\n");
 for(i=0;i<SN;i++)
 {
  printf("%ld %s ",stu[i].Num,stu[i].Name);

  for(j=0;j<CN;j++)
  {
   printf("%.1f ",stu[i].Score[j]);
  }
  printf("%.3f \n",stu[i].AveSc);
 }

 printf("三门课的总平均成绩为%.3f\n\n",aveT);

 for(k=0;k<CN;k++)
 {
  printf("第%d门课的平均成绩为%.3f\n",k+1,ave[k]);
 }
}
// 3)编写程序:建立一个链表,每个结点包括课程名、学分数。输入一门课程的名称,在链表中查找是否有这门课,若未找到,则
// 从键盘输入该课程的学分数,将这门课插入到链表的尾部,然后输出修改后链表各结点的数据。学会链表的建立、查找、插入等
// 基本操作。要求:函数create输入6门课程及学分,建立链表;函数print输出链表的各结点;函数find查找某课程,若找到,返回
// 指向该结点的指针变量,否则返回NULL;函数insert将新结点插入到链表的最后,返回链表的头指针;主函数中先调用create函数
// 和print函数;然后输入要查找的课程名,调用find函数后,若找到,输出相关信息;否则输入学分数,调用insert函数,将该课程
// 插入到链表中;最后调用print函数,输出插入后的链表。

#include <stdio.h>
#include <string.h>
#define CN 6//课程数 6

struct course//课程结构体
{
 char Cname[20];//课程名
 double Credit;//学分数
 struct course *next;//指向下一课程结点的指针
};

//函数create输入6门课程及学分,建立链表
struct course *create(int n)
{
 int i;
 char name[20];
 double credit;

 struct course *head=NULL,*pnew,*ptail;

 for(i=1;i<=n;i++)
 {
  pnew=(struct course *)malloc(sizeof(struct course));

  printf("请输入一个课程名和学分数:\n");
  scanf("%s%lf",name,&credit);

  strcpy(pnew->Cname,name);
  pnew->Credit=credit;

  if(head==NULL)
   head=ptail=pnew;
  else
  {
   ptail->next=pnew;
   ptail=pnew;
  }
 }
 ptail->next=NULL;//尾结点
 return head;
}

//函数print输出链表的各结点
void print(struct course *head)
{
 struct course *p=head;

 printf("课程名 学分:\n\n");
 while(p!=NULL)
 {
  printf("%s %.1f \n",p->Cname,p->Credit);
  p=p->next;
 }
}

//函数find查找某课程,若找到,返回指向该结点的指针变量,否则返回NULL
struct course *find(struct course *head,char *name,struct course *ps)
{
 struct course *p=head;

 while(p!=NULL&&(strcmp(p->Cname,name)!=0))
 {
  p=p->next;
 }
 if(p!=NULL)
 {
  ps=p;
  return ps;
 }
 else
  return NULL;
}

//函数insert将新结点插入到链表的最后,返回链表的头指针
struct course *insert(struct course *head,struct course *pnew)
{
 struct course *p,*pb;
 p=pb=head;

 if(head==NULL)
  head=pnew;
 else
 {
  while(p!=NULL)
  {
   pb=p;
   p=p->next;
  }
  pb->next=pnew;
  pb=pnew;
  pb->next=NULL;
 }
 return head;
}

//建立一个链表,每个结点包括课程名、学分数。输入一门课程的名称,在链表中查找是否有这门课,若未找到,则
// 从键盘输入该课程的学分数,将这门课插入到链表的尾部,然后输出修改后链表各结点的数据。
void main()
{
 int i;
 char cname[20];
 double credit;
 struct course *head,*ps,*pc;

 head=create(CN);
 ps=pc=(struct course *)malloc(sizeof(struct course));

 printf("请输入一门课的名称:\n");
 scanf("%s",cname);
 strcpy(pc->Cname,cname);

 if(find(head,cname,ps)==NULL)
 {
  printf("请输入该门课的学分:\n");
  scanf("%lf",&credit);
  pc->Credit=credit;
  pc->next=NULL;
 }

 head=insert(head,pc);

 print(head);
}


// 4) 编写程序:建立一个链表,每个结点包括职工号、职工姓名、工资。从键盘输入工资salary,要求将链表中工资低于salary的结点
// 全部删除,并输出修改后的链表。学会链表的建立、删除等基本操作。要求:用函数create输入6名职工及信息,建立链表;用函数
// print输出链表的各结点;用函数delete完成结点的删除;主函数中先调用create函数和print函数;然后输入工资salary,调用delete
// 函数删除结点;调用print函数,将删除后的链表输出。

#include <stdio.h>
#include <string.h>
#define WN 3//职工数 6

struct worker//职工结构体
{
 long Wnum;//职工号
 char Wname[20];//职工姓名
 double Salary;//工资
 struct worker *next;//指向下一职工结点的指针
};

//函数create输入6名职工及信息,建立链表
struct worker *create(int n)
{
 int i;
 long num;
 char name[20];
 double salary;

 struct worker *head=NULL,*pnew,*ptail;

 for(i=1;i<=n;i++)
 {
  pnew=(struct worker *)malloc(sizeof(struct worker));

  printf("请输入一个职工号、职工姓名和工资:\n");
  scanf("%ld%s%lf",&num,name,&salary);

  pnew->Wnum=num;
  strcpy(pnew->Wname,name);
  pnew->Salary=salary;

  if(head==NULL)
   head=ptail=pnew;
  else
  {
   ptail->next=pnew;
   ptail=pnew;
  }
 }
 ptail->next=NULL;//尾结点

 return head;
}

//函数print输出链表的各结点
void print(struct worker *head)
{
 struct worker *p=head;

 printf("职工号 职工姓名 工资:\n\n");
 while(p!=NULL)
 {
  printf("%ld %s %.1f \n",p->Wnum,p->Wname,p->Salary);
  p=p->next;
 }
}

//函数find查找某职工,若找到,返回指向该结点的指针变量,否则返回NULL
struct worker *find(struct worker *head,double salary,struct worker *ps)
{
 struct worker *p=head;

 while(p!=NULL&&(p->Salary!=salary))
 {
  p=p->next;
 }
 if(p!=NULL)
 {
  ps=p;
  return ps;
 }
 else
  return NULL;
}

//函数insert将新结点插入到链表的最后,返回链表的头指针
struct worker *insert(struct worker *head,struct worker *pnew)
{
 struct worker *p,*pb;
 p=pb=head;

 if(head==NULL)
  head=pnew;
 else
 {
  while(p!=NULL)
  {
   pb=p;
   p=p->next;
  }
  pb->next=pnew;
  pb=pnew;
  pb->next=NULL;
 }
 return head;
}

//用函数delete完成结点的删除
struct worker *deletew(struct worker *head,double salary)
{
 struct worker *p=head,*pold=head;

    //删除满足指定条件的链表头部的连续若干节点
 p=head;
 while(head!=NULL&&head->Salary<salary)
 {
  head=head->next;
  printf("%.3f has been deleted! \n\n",p->Salary);
  free(p);
  p=head;
 }

 if(head==NULL)
  return head;

    //删除满足指定条件的链表头部的连续若干节点
 p=head->next;
 pold=head;
 while(p!=NULL)
 {
  if(p->Salary<salary)
  {
   pold->next=p->next;
   printf("%.3f has been deleted! \n\n",p->Salary);
   free(p);
   p=pold->next;
  }
  else
  {
   pold=p;
   p=p->next;
   
 }
 
 return head;
}

//建立一个链表,每个结点包括职工名、学分数。输入一门职工的名称,在链表中查找是否有这门课,若未找到,则
// 从键盘输入该职工的学分数,将这门课插入到链表的尾部,然后输出修改后链表各结点的数据。
void main()
{
 int i;
 long num;
 char wname[20];
 double salary;
 struct worker *head,*ps,*pw;

 head=create(WN);
 ps=pw=(struct worker *)malloc(sizeof(struct worker));

 printf("请输入工资:\n");
 scanf("%lf",&salary);
 pw->Salary=salary;

 head=deletew(head,salary);

 if(find(head,salary,ps)==NULL)
 {
  printf("请输入该职工的工号和姓名:\n");
  scanf("%ld",&num);
  scanf("%s",wname);
  pw->Wnum=num;
  strcpy(pw->Wname,wname);
  pw->next=NULL;
 }

 head=insert(head,pw);

 print(head);
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有