第九章 结构体与共用体

C程序设计实验报告

一、实验项目:

1、结构体变量的应用。

2、结构体数组的应用。

3、共用体的应用。

4、机构体指针的应用。

姓名:宋梦南    实验地点:教学楼514教室     实验时间:6月28日

二、实验目的

         9.3.1 结构体变量的应用

  • 定义结构体类型struct date,它含有年、月、日3个成员;
  • 定义struct date类型的变量,并从键盘输入初值;
  • 利用循环语句,计算天数;
  • 利用分支结构,判断闰年。

    9.3.2 结构体数组的应用

  • 定义候选人struct person结构体数组,含有姓名、得票数两个成员;
  • 定义struct person结构体数组,人数自定,初始票数为0;
  • 利用循环输入候选人名字,该人员票数加1;
  • 输入的候选人不是规定的候选人时,相当于废票,不累计。

    9.3.3 共用体的应用

  • 定义结构体类型,其成员有编号、姓名、职业和班级(或职务);
  • 定义该结构体类型的数组,可有若干个数组元素;
  • 利用该循环语句输入每条记录的数据,若该记录的职业为‘s’,则该记录是学生,输入该学生的班级;若该记录的职业是’t‘,则该记录是教师的,输入该教师的职务;
  • 根据记录的职业来判断,使用哪个printf()语句输出记录。

    9.3.4 结构体指针的应用

  • 定义结构体类型,其成员有人员编号、下一人员编号(地址);
  • 定义该结构体类型的数组,可有n个数组元素;
  • n个人围成一圈,可以考虑用结构体数组元素中的“下一人员编号”来实现,但最后一个元素的“下一人员编号”指向第一个。

三、实验内容

实验9.3.1

1.问题的简单描述:试利用结构体类型描述年、月、日,输入一个日期,统计日期是本年度第多少天。

2.流程图:

3.实验代码:

#include<stdio.h>
 main()
{
    struct date 
    {
        int year;
        int month;
        int day;
    };
    struct date a;
    int i,days=0;
    printf("输入年,月,日:");
    scanf("%d,%d,%d",&a.year,&a.month,&a.day);
    for(i=1;i<a.month;i++)
    {
        if(i==1||i==3||i==5||i==7||i==8||i==10||i==12)days+=31;
        else if(i==4||i==6||i==9||i==11)days+=30;
        else if(a.year%4==0&&a.year%100!=0||a.year%400==0)days+=29;
             else days+=28;
    }
    days+=a.day;
    printf("%d年%d月%d日是该年的第%d天",a.year,a.month,a.day,days);
 } 

4.问题分析:一开始怎么运行结果都为87天,后来同桌告诉我day的初始值要改成0才能行,后来才知道没有加static,默认为auto 型,此时,不给初值,变量的初值是随机的。所以有些时候不赋初始值会出错。

5.运行效果:

9.3.2 :结构体数组的应用

1.问题的简单描述:在选举中,假设有6位候选人,有10个人参加投票(只能对一位候选人投票),用结构体数据统计各候选人的得票数。

2.流程图:

 

3.实验代码:

#include<stdio.h>
#include<string.h>
struct person
{
    char name[20];
    int count;
}a[6]={"zhang",0,"li",0,"wang",0,"zhao",0,"liu",0,"zhu",0};
main()
{
    int i,j;
    char abc[20];
    for(i=1;i<=10;i++)
    {
        printf("输入候选人:");
        scanf("%s",abc);
        for(j=0;j<6;j++)
             if(strcmp(abc,a[j].name)==0)
                  a[j].count++;
    }
    for(j=0;j<6;j++)
    printf("%s,%d\n",a[j].name,a[j].count);
}

4.问题分析:这个程序当中的strcmp(s1,s2) 判断两个字符串s1和s2是否相同,相同返回true ,不同返回false,因为我们是要判断输入的名字如果一样则加一票,就是字符串的比较,所以要用到这个函数,它的头文件是
string.h,还要注意的就是字符串要用%s。

5.运行效果:

 

9.3.3:共用体的应用

1.问题的简单描述:在选举中,假设有6位候选人,有10个人参加投票(只能对一位候选人投票),用结构体数组统计各候选人的得票数。

 2.流程图:

 

3.实验代码:

#include<stdio.h>
#include<stdlib.h>
struct
{
    int number;
    char name[30];
    char job;
    union
    {
        int classes;
        char position[10];
        }category; 
    }person[2];
    main()
    {
        int i;
        for(i=0;i<2;i++)
        {
            fflush(stdin);
            scanf("%d%s%s",&person[i].number,&person[i].name,&person[i].job);
            if(person[i].job=='s')
            {
                 printf("请输入班级:"); 
                 scanf("%d",&person[i].category.classes);
            }
            else if(person[i].job=='t')
            {
                printf("请输入职业:"); 
                scanf("%s",&person[i].category.position);
            } 
            else 
            {
                printf("input error!");
                abort();
            }
        }
        printf("\n");
        printf("编号\t\t姓名\t\t职业\t\t班级/职务\n");
           for(i=0;i<2;i++)
                if(person[i].job=='s')
                   printf("%d\t\t%s\t\t%c\t\t%d\n",person[i].number,person[i].name,person[i].job,person[i].category.classes);
                else 
                   printf("%d\t\t%s\t\t%c\t\t%s\n",person[i].number,person[i].name,person[i].job,person[i].category.position);   
    }

4.问题分析:

在这个程序中用到了fflush(stdin);这个功能是清空输入缓冲区,是为了确保不影响后面的数据读取(例如在读完一个字符串后紧接着又要读取一个字符,此时应该先执行fflush(stdin);),还用到了函数 abort() 它的头文件是#include <stdlib.h>,用来中止程序直接跳出,这些
都需要我们自己去翻书学习查阅的,还有如果是从键盘上获取的为一个数组,那就不需要用“&”。

5.运行效果:

9.3.4:结构体指针的应用

1.问题的简单描述:n个人围成一个圈,从第s个人开始按顺时钟1,2,3,...,m的顺序报数,数到m的人出圈,然后从出圈的下一个人开始重复此过程,输出所有出圈人的顺序,n,s,m从键盘输入。

 2.流程图:

 

3.实验代码:

#include<stdio.h>
#define N 10
struct child
{
    int no;
    int next;
};
struct child link[N];
main()
 {
    int i,n,m,s,count,h;
    printf("输入围圈人数,出圈报数,开始报数位置:");
    scanf("%d%d%d",&n,&m,&s);
    for(i=1;i<=n;i++)
    {
        if(i==n)
            link[i].next=1;
        else
            link[i].next=i+1;
        link[i].no=i;
    }
    count=0;
    if(s==1)
        h=n;
    else 
        {
            h=s-1;
        }
    printf("出圈顺序为:");
    while(count<n-1)
    {
        i=0;
        while(i!=m)
        {
            h=link[h].next;
            if(link[h].no)
                i++;
        }
        printf("%d, ",link[h].no);
        link[h].no=0;
        count++;
    } 
    for(i=1;i<=n;i++)
    {
        if(link[i].no!=0)
        printf("%d",link[i].no);
    }
}

4.问题分析:如果没有书上的提示,从头到尾都是自己解决的话,我想会比较困难,首先要分析我们怎么才能实现这个程序,首先就是要明白结构体的内容里应该放什么,这里很容易遗漏掉的应该是“下一人员的编号”,还要注意的是当没执行一次,也就是出圈一人,总人数也会随之改变,编号也会改变,就比如题中出圈一人,那么出圈的那个人就要立刻编号为0,才能保证接下来重新开始的为1,当剩下最后一人,报数停止,输出最后一人的“人员编号”。

5.运行效果:

三、实验小结

1.一定要养成”定义变量就初始化“的好习惯,在使用变量”进行运算“前,一定要注意检查变量是否已按自己的要求进行了赋值。

2在使用结构体函数嵌套时,要注意结构体名称逐级输入。

3.对于常见的一些表达我们要熟练,就比如这次又遇到的闰年,要烂熟于心。

4.fflush(stdin)这个函数功能是清空输入缓冲区,是为了确保不影响后面的数据读取。

5.abort()函数的头文件是#include <stdlib.h>,用来中止程序直接跳出。

6.要比较两个字符串时应该要用strcmp(s1,s2) 函数判断两个字符串s1和s2是否相同,相同返回true ,不同返回false。

7.很多人疑问为什么scanf有的要&有的不要,因为如果它是数组就可以不要,如果不是就要加上,就比如实验中的:  &person[i].category.classes        person[i].category.position



posted on 2019-06-30 22:24  宋梦南  阅读(183)  评论(0编辑  收藏  举报

导航