
结构体与共用体综合测试
1 定义一个结构体变量(包括年,月,日)。计算该日在本年中是第几天,注意闰年
问题。
解:
 struct
 { int year;
   int month;
   int day;
 } date;
 main()
 { int days;
   printf("input year,month,day:");
   scanf("%d,%d,%d",&year,month,day);
   switch(date.month)
    { case 1: days=date.day; break;
      case 2: days=date.day+31; break; 
      case 3: days=date.day+59; break;
      case 4: days=date.day+90; break;
      case 5: days=date.day+120; break;
      case 6: days=date.day+151; break;
      case 7: days=date.day+181; break;
      case 8: days=date.day+212; break;
      case 9: days=date.day+243; break;
      case 10: days=date.day+273; break;
      case 11: days=date.day+304; break;
      case 12: days=date.day+334; break;
   }
  if((date.year%4==0&&date.year%100!=0||date.year%400==0)&&date.month>=3)
     days+=1;
  printf("\n%d/%d is the %dth day in %d."date.month,date.day,days,date.year);
 }
2 写一个函数days,实现上面的计算。由主函数将年,月,日传递给days函数,计算
后将日数传回主函数输出。
 解:
 struct y_m_d
 { int year;
   int month;
   int day;
 } date;
 int days(struct y_m_d datel)
 { int sum;
   switch(datel.month)
    { case 1: sum=date1.day; break;
      case 2: sum=date1.day+31; break; 
      case 3: sum=date1.day+59; break;
      case 4: sum=date1.day+90; break;
      case 5: sum=date1.day+120; break;
      case 6: sum=date1.day+151; break;
      case 7: sum=date1.day+181; break;
      case 8: sum=date1.day+212; break;
      case 9: sum=date1.day+243; break;
      case 10: sum=date1.day+273; break;
      case 11: sum=date1.day+304; break;
      case 12: sum=date1.day+334; break;
    }
   if((date1.year%4==0&&date1.year%100!=0||date1.year%400==0)&&date1.month>=3)
     sum+=1;
   return(sum);
 }
 main()
 { printf("input year,month,day:");
   scanf("%d,%d,%d",&year,month,day);
   printf("\n");
   printf("%d/%d is the %dth day in %d."date.month,date.day,days(date),date.year);
 }
3 编写一个函数printf,打印一个学生的成绩数组,该数组中有5个学生的数据记录
每个记录包括(num,name,score[3],用主函数输入这些记录,用printf函数输出这些记录
 解:
 #define N 5
 struct student
 { char num[6];
   char name[8];
   int score[4];
 } stu[N];
 main()
 { int i,j;
   for(i=0;i<N;i++)
    { printf("\ninput score of student %d:\n",i+1);
      printf("No.:");
      scanf("%s",stu[i].num);
      printf("name:");
      scanf("%s",stu[i].name);
      for(j=0;j<3;j++)
       { printf("score %d:",j+1);
         scanf("%d",&stu[i].score[j]);
       }
      printf("\n");
    }
   print(stu);
  }
 print(struct student stu[6])
  { int i,j;
    printf("\n NO. name score1 score2 score3\n");
    for(i=0;i<N;i++)
     { printf("%5s%10s",stu[i].num,stu[i].name);
       for(j=0;j<3;j++)
         printf("%9d",stu[i].score[j]);
       printf("\n");
     }
  }
4 在上题的基础上,编写一个函数input,用来输入5个学生的数据记录.
  解:
 #define N 5
 struct student
 { char num[6];
   char name[8];
   int score[4];
 }stu[N];
 input(struct student stu[])
 { int i,j;
   for(i=0;i<N;i++)
    { printf("\ninput scores of student %d:\n",i+1);
      printf("No.:");
      scanf("%s",stu[i].num);
      printf("name:");
      scanf("%s",stu[i].name);
      for(j=0;j<3;j++)
       { printf("score %d:",j+1);
         scanf("%d",&stu[i].score[j]);
       }
      printf("\n");
    }
 }
 写一个main函数,调用input函数以及题3中提供的print函数,就可以完成对学生
 数据的输入和输出.
5 有10个学生,每个学生的数据包括学号,姓名,3门课的成绩,从键盘输入10个学生的
数据,要求打印出3门课的总平均成绩,以及最高分的学生的数据(包括学号,姓名,3门课
成绩,平均分数).
 #define N 10
 struct student
 { char num[6];
   char name[8];
   int score[4];
   float avr;
 } stu[N];
 main()
 { int i,j,maxi,sum;
   float average;
   for(i=0;i<N;i++)
    { printf("\ninput score of student %d:\n",i+1);
      printf("No.:");
      scanf("%s",stu[i].num);
      printf("name:");
      scanf("%s",stu[i].name);
      for(j=0;j<3;j++)
       { printf("score %d:",j+1);
         scanf("%d",&stu[i].score[j]);
       }
     }
    average=0;
    max=0;
    maxi=0;
    for(i=0;i<N;i++)
     { sum=0;
       for(j=0;j<3;j++)
         sum+=stu[i].score[j];
       stu[i].avr=sum/3.0;
       average+=stu[i].avr;
       if(sum>max)
        { max=sum;
          maxi=i;
        }
      }
    average/=N;
    printf("NO. name score1 score2 score3 average\n");
    for(i=0;i<N;i++)
     { printf("%5s%10s",stu[i].num,stu[i].name);
       for(j=0;j<3;j++)
        printf("%9d",stu[i].score[j]);
       printf("%8.2f\n",stu[i].avr);
     }
    printf("average=%6.2f\n",average);
    printf("The highest score is: %s,score total: %d",stu[maxi].name,max);
 }  
6 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),
     指向字符串开始的空间.new(n)表示分配n个字节的内存空间.
 #define NULL 0
 #define NEWSIZE 1000
 char newbuf[NEWSIZE];
 char *newp=newbuf;
 char *new(int n)
  { if(newp+n<=newbuf+NEWSIZE)
     { newp=newp+n;
       return(newp-n);
     }
    else
       rerurn(NULL);
  }
7 写一个函数free,将上题用new函数占用的空间释放.free(p)表示将p(地址)指向
     的单元以后的内存段释放.
解:
 #define NULL 0
 #define NEWSIZE 1000
 char newbuf[NEWSIZE];
 char *newp=newbuf;
 free(char *p)
  { if((p>=newbuf)&&(p<newbuf+NEWSIZE))
     new=p;
  }
8 已有a,b两个链表,每个链表中的结点包括学号,成绩,要求把两个链表合并,按学号
     升序排列.
解:
 #include<stdio.h>
 #define NULL 0
 #define LEN sizeof(struct student)
 struct student
 { long num;
   int score;
   struct student *next;
 };
 struct student listA,listB;
 int n,sum=0;
 main()
 { struct student *creat(void);
   struct student *insert(struct student*,struct student*);
   void pint(struct student *);
   struct student *ahead,*bhead,*abh;
   printf("\ninput list a:\n");
   ahead=creat();
   sum=sum+n;
   printf("input list b:\n");
   bhead=creat();
   sum+=n;
   abh=insert(ahead,bhead);
   print(abh);
 }
 struct student *creat(void)
 { struct student *p1,*p2,*head;
   n=0;
   p1=p2=(struct student *)malloc(LEN);
   printf("if number&scores of student:\n");
   printf("if number is 0,stop inputing.\n");
   scanf("%ld,%d",&p1->num,&p2->score);
   head=NULL;
   while(p1->num!=0)
    { n+=1;
      if(n==1) head=p1;
      else p2->next=p1;
      p2=p1;
      p1=(struct student *)malloc(LEN);
      scanf("%ld,%d",&p1->num,&p2->score);
    }
   p2->next=NULL;
   return(head);
 }
 struct student *insert(struct student *ah,struct student *bh)
 { struct student * pa1,* pa2,* pb1,* pb2;
   pa2=pa1=ah;
   pb2=pb1=bh;
   do
    { while((pb1->num>pa1->num)&&(pa1->next!=NULL))
      { pa2=pa1;
        pa1=pa1->next;
      }
      if(pb1->num<=pa1->num)
       { if(ah==pa1)
          ah=pb1;
         else pa2->next=pb1;
         pb1=pb1->next;
         pb2->next=pa1;
         pa2=pb2;
         pb2=pb1;
        }
     }
    while((pa1->next!=NULL)||pa1==NULL&&pb1!=NULL));
      if((pb1->num>pa1->num)&&(pa1->next==NULL))
         pa1->next=pb1;
    return(ah);
 }
 void print(struct student *head)
  { struct student *p;
    printf("\nThere are %d records:\n",sum);
    p=head;
    if(p!=NULL)
      do
       { printf("%ld%d\n",p->num,p->score);
         p=p->next;
       }
      while(p!=NULL);
  }
9 13个人围成一圈,从第一个人开始顺序报号1,2,3.凡报到"3"者退出圈子.找出最后
     留在圈子中的人原来的序号.
解:
 #define N 13
 struct person
 { int number;
   int nextp;
 }link[N+1];
 main()
 { int i,count,h;
   for(i=1;i<=N;i++)
    { if(i==N)
       link[i].nextp=1;
      else
       link[i].nextp=i+1;
       link[i].number=i;
     }
    printf("\n");
    count=0;
    h=N;
    printf("sequence that persons leave the circle:\n");
    while(count<N-1)
     { i=0;
       while(i!=3)
        { h=link[h].nextp;
          if(link[h].number)
            i++;
        }
       printf("%4d",link[h].number);
       link[h].number=0;
       count++;
     }
    printf("\nThe last one is");
    for(i=1;i<=N;i++)
     if(link[i].number)
       printf("%3d",link.number);
 }
10 有两个链表a和b,设结点中包含学号,姓名.从a链表中删去与b链表中有相同学号的那些
      结点.
解:
 #define LA 4
 #define LB 5
 #define NULL 0
 struct student
 { char num[6];
   char name[8];
   struct student *next;
 } a[LA],b[LB];
 main()
 { struct student a[LA]={{"101","wang"},{"102","li"},{"105","zhang"},{"106","
   wei"}};
   struct student b[LB]={{"103","zhang"},{"104","ma"},{"105","chen"},{"107","
   guo"},{"108","lui"}};
   int i,j;
   struct student *p,*p1,*p2,*Pt,*head1,*head2;
   head1=a;  head2=b;
   printf("\nlist a:\n");
    for(p1=head1,i=1;p1<a+LA;i++)
     { p=p1;
       p1->next=a+i;
       printf("%8s%8s\n",p1->num,p1->name);
       p1=p1->next;
     }
    p1->next=NULL;
    printf("\n list b:\n");
    for(p2=head2,i=1;p2<b+LB;i++)
     { p=p2;
       p2->next=b+i;
       printf("%8s%8s\n",p2->num,p2->name);
       p2=p2->next;
     }
    p2->next=NULL;
    printf("\n");
    p1=head1;
    while(p1!=NULL)
     { p2=head2;
       while(p2!=NULL&&strcmp(p1->num,p2->num)!=0)
        p2=p2->next;
       if(strcmp(p1->num,p2->num)==0)
        if(p1==head1)
          head1=p1->next;
        else
          p->next=p1->next;
       p=p1;
       p1=p1->next;
     }
    p1=head1;
    printf("\n result:\n");
    while(p1!=NULL)
     { printf("%7s%7s\n",p1->num,p1->name);
       p1=p1->next;
     }
 }
11 建立一个链表,每个结点包括:学号,姓名,性别,年龄.输入一个年龄,如果链表中
      的结点所包含的年龄等于此年龄,则将此年龄删去.
解:
 #define NULL 0    
 #define LEN sizeof(struct student)
 struct student
 { char num[6];
   char name[8];
   char sex[2];
   int age;
   struct student *next;
 } stu[10];
 main()
 { struct student *p,*pt,*head;
   int i,length,iage,flag=1;
   int find=0;
   while(flag==1)
   { printf("Input length of list(<10):");
     scanf("%d",&length);
     if(length<10)
       flag=0;
   }
 for(i=0;i<length;i++)
 { p=(struct student *)malloc(LEN);
   if(i==0)
     head=pt=p;
   else
     pt->next=p;
   pt=p;
   printf("NO:");
   scanf("%s",p->num);
   printf("name:");
   scanf("%s",p->name);
   printf("sex:");
   scanf("%s",p->sex);
   printf("age:");
   scanf("%d",&p->age);
 }
 p->next=NULL;
 p=head;
 printf("\n NO. name sex age\n");
 while(p!=NULL)
  { printf("%4s%8s%6s%6d\n",p->num,p->name,p->sex,p->age);
    p=p->next;
  }
 printf("input age:");
 scanf("%d",&iage);
 pt=head;
 p=pt;
 if(pt->age==iage)
  { p=pt->next;
    head=pt=p;
    find=1;
  }
 else
    pt=pt->next;
 while(pt!=NULL)
  { if(pt->age==iage)
     { p->next=pt->next;
       find=1;
     }
    else
       p=pt;
       pt=pt->next; 
  }
 if(!find)
   printf("Not found %d.",iage);
 p=head;
 printf("\nNO. name sex age\n");
 while(p!=NULL) 
  { printf("%4s%8s",p->num,p->name);
    printf("%6s%6d\n",p->sex,p->age);
    p=p->next;
  }
 12 将一个链表按逆序排列,即将链头当链尾,链尾当链头.
解:
 #define NULL 0
 struct stu
 { int num;
   struct stu *next;
 }
 main()
 { int len=1,i;
   struct stu *p1,*p2,*head,*new,*newhead;
   p1=p2=head=(struct stu *) malloc(sizeof(struct stu));
   printf("input number(0:list end):");
   scanf("%d",&p1->num);
   while(p1->num!=0)
    { p1=(struct stu *) malloc(sizeof(struct stu));
      printf("input number(0:list end):");
      scanf("%d",&p1->num);
      if(p1->num==0)
        p2->next=NULL;
      else
        { p2->next=p1;
          p2=p1;
          len++;
        }
      p1=head;
      printf("\n the original list:\n");
      do 
        { printf("%4d",p1->num);
          if(p1->next!=NULL)
           p1=p1->next;
        }
      while(p1->next!=NULL)
      printf("%4d",p1->num);
      for(i=0;i<len;i++)
       { p2=p1=head;
         while(p1->next!=NULL)
          { p2=p1;
            p1=p1->next;
          }
         if(i==0)
           newhead=new=p1;
         else
           new=new->next=p1;
         p2->next=NULL;
       }
      printf("\n\n The new list:\n");
      p1=newhead;
      for(i=0;i<len;i++)
       { printf("%4d",p1->num);
         p1=p1->next;
       }
      printf("\n");
 }       
 

 
											





 
	     
										 
										
					
	

