打印本文 打印本文  关闭窗口 关闭窗口  
C语言程序设计(第7章结构体与共用体)2
作者:佚名  文章来源:不详  点击数  更新时间:2008/4/18 13:59:53  文章录入:杜斌  责任编辑:杜斌

7.2 结构体数组的定义和引用
    单个的结构体类型变量在解决实际问题时作用不大,一般是以结构体类型数组的形式出现。结构体类型数组的定义形式为:
struct stu /*定义学生结构体类型*/
{
    char name[20]; /*学生姓名*/
    char sex; /*性别*/
    long num; /*学号*/
    float score[3]; /*三科考试成绩*/
};
struct stu stud[20]; /* 定义结构体类型数组stud ,*/
/ *该数组有2 0个结构体类型元素* /
其数组元素各成员的引用形式为:
stud[0].name 、stud[0].sex、stud[0].score[i];
stud[1].name、stud[1].sex、stud[1].score[i];
. . .
. . .
stud[19].name、stud[19].sex、stud[19].score[i];

[例7-1] 设某组有4 个人,填写如下的登记表,除姓名、学号外,还有三科成绩,编程实现对表格的计算,求解出每个人的三科平均成绩,求出四个学生的单科平均,并按平均成绩由高分到低分输出。
NumberNameEnglishMathemrPhysicsAverage
1Liping789876.
2Wanglin669086.
3Jiangbo897076.
4Yangming9010067.


题目要求的问题多,采用模块化编程方式,将问题进行分解如下:
1) 结构体类型数组的输入。
2) 求解各学生的三科平均成绩。
3) 按学生的平均成绩排序。
4) 按表格要求输出。
5) 求解组内学生单科平均成绩并输出。
6) 定义m a i n ( )函数,调用各子程序。
第一步,根据具体情况定义结构体类型。
struct stu
{
    char name[20]; /*姓名* /
    long number; /*学号* /
    float score[4]; /* 数组依此存放English、Mathema、Physics,及Average*/
} ;
    由于该结构体类型会提供给每个子程序使用,是共用的,所以将其定义为外部的结构体类型,放在程序的最前面。
第二步,定义结构体类型数组的输入模块。
void input(arr,n) /*输入结构体类型数组arr 的n个元素*/
struct stu arr[];
int n;
{
     int i,j;
    char temp[30];
    for (i=0;i<n;i++)
    {
        printf("\ninput name,number,English,mathema,physic\n"); /*打印提示信息* /
        gets(arr[i].name); /* 输入姓名*/
        gets(temp); /* 输入学号*/
        arr[i].number = atol(temp);
        for(j = 0; j < 3; j++)
        {
            gets(temp); /*输入三科成绩* /
            arr[i].score[j] = atoi(temp);
        }
    }
}
第三步,求解各学生的三科平均成绩。
在结构体类型数组中第i个元素arr[i]的成员score的前三个元素为已知,第四个Average需计算得到。
void aver(arr,n)
struct stu arr[];
int n;
{
    int i,j;
    for(i=0;i<n;i++) /*n个学生*/
    {
        arr[i].score[3] = 0;
        for(j=0;j<3;j++)
            arr[i].score[3]=arr[i].score[3]+arr[i].score[j]; /* 求和*/
        arr[i].score[3]=arr[i].score[3] /3; /* 平均成绩* /
    }
}
第四步,按平均成绩排序,排序算法采用冒泡法。
void order(arr,n)
struct stu arr[];
int n;

    struct stu temp;
    int i,j,x,y;
    for(i = 0; i < n - 1; i++)
        for( j = 0; j < n - 1 - i; j++)


            if (arr[j].score[3]>arr[j+1].score[3])
            { 
                temp=arr[j]; /* 结构体类型变量不允许以整体输入或输出,但允许相互赋值* /
                arr[j]=arr[j+1]; /*进行交换* /
                arr[j + 1] = temp;
            }
}
第五步,按表格要求输出。
void output(arr,n) /*以表格形式输出有n个元素的结构体类型数组各成员*/
int n;struct stu arr[];
{
    int i,j;
    printf("********************TABLE********************\n"); /* 打印表头*/
    printf("----------------------------------------------------\n");
    /*输出一条水平线*/
    printf("|%10s|%8s|%7s|%7s|%7s|%7s|\n","Name","Number", "English", "Mathema","physics","average");
    /*输出效果为:| Name| Number|English|Mathema|Physics|Average|*/
    printf("----------------------------------------------------\n");
    for (i=0;i<n;i++)
    {
        printf("|%10s|%8ld|",arr[i].name,arr[i].number); /* 输出姓名、学号*/
        for(j=0;j<4;j++)
        printf("%7.2f|",arr[i].score[j]);/*输出三科成绩及三科的平均*/
        printf("\n");
        printf("---------------------------------------------------\n");
    }
}
第六步,求解组内学生单科平均成绩并输出。在输出表格的最后一行,输出单科平均成绩及总平均。
void out_row(arr,n) /*对n个元素的结构体类型数组求单项平均*/
int n;
struct stu arr[];
{
    float row[4]={0,0,0,0};/*定义存放单项平均的一维数组*/
    int i,j;
    for( i = 0; i < 4; i++)
    {
        for(j=0; j<n; j++)
        row[i] = row[i] + arr[j].score[i]; /* 计算单项总和*/
        row[i]=row[i]/n; /* 计算单项平均*/
    }
    printf("|%19c|",’ ’); /* 按表格形式输出*/
    for (i=0;i<4;i++)
    printf("%7.2f|",row[i]);
    printf("\n------------------------------------------\n");
}
第七步,定义main( )函数,列出完整的程序清单。
#include <stdlib.h>
#include <stdio.h>
struct stu
{
    char name[20];
    long number;
    float score[4];
} ;
main( )
{
    void input(); /*函数声明*/
    void aver();
    void order();
    void output();
    void out_row();
    struct stu stud[4]; /* 定义结构体数组*/
    float row[3];
    input(stud, 4); /*依此调用自定义函数*/
    aver(stud,4);
    order(stud,4);
    output(stud, 4);
    out_row(stud,4);
}
/****************************/


void input(arr,n)
struct stu arr[];
int n;
{
    int i,j;
    char temp[30];
    for (i=0;i<n;i++)
    {
        printf("\nInput Name,Number,English,Mathema,Physic\n");
        gets(arr[i].name);
        gets(temp);
        arr[i].number=atol(temp);
        for(j=0;j<3;j++)
        {
            gets(temp);
            arr[i].score[j]=atoi(temp);
        }
    }
}
/ *****************************************/
void aver(arr,n)
struct stu arr[];
int n;
{
    int i,j;
    for(i=0;i<n;i++)
    {
        arr[i].score[3]=0;
        for(j=0;j<3;j++)
            arr[i].score[3]=arr[i].score[3]+arr[i].score[j];
        arr[i].score[3]=arr[i].score[3]/3;
    }
}
/*********************************************/
void order(arr,n)
struct stu arr[];
int n;
{
    struct stu temp;
    int i,j,x,y;
    for(i=0;i<n-1;i++)
        for(j=0;j<n-1-i;j++)
            if (arr[j].score[3]>arr[j+1].score[3])
            {
                temp=arr[j];
                arr[j] = arr[j+1];
                arr[j+1]=temp;
            }
}
/**********************************************/
void output(arr,n)
int n;
struct stu arr[];
{
    int i,j;
    printf("********************TABLE********************\n");
    printf("-------------------------------------------------\n");
    printf("|%10s|%8s|%7s|%7s|%7s|%7s|\n","Name","Number","English","mathema","physics","average");
    printf("-------------------------------------------------\n");
    for (i=0;i<n;i++)
    {
        printf("|%10s|%8ld|",arr[i].name,arr[i].number);
        for(j=0;j<4;j++)
        printf("%7.2f|",arr[i].score[j]);
        printf("\n");
        printf("----------------------------------------------\n");
    }
}
/*********************************************/
void out_row(arr,n)
int n;
struct stu arr[];
{
    float row[4]={0,0,0,0};
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<n;j++)
        row[i]=row[i]+arr[j].score[i];
        row[i]=row[i]/n;
    }


    printf("|%19c|",’ ’);
    for (i=0;i<4;i++)
    printf("%7.2f|",row[i]);
    printf("\n-------------------------------------------------------\n");
}
运行程序:
Input Name,Number,English,Mathema,Physic
Liping
1
78
98
76
Input Name,Number,English,Mathema,Physic
Wangling
2
66
90
86
Input Name,Number,English,Mathema,Physic
Jiangbo
3
89
70
76
Input Name,Number,English,Mathema,Physic
Yangming
4
90
100

********************* T A B L E ************************
---------------------------------------------
|   Number|   Name|English| Mathema| Physics| Average|
---------------------------------------------
| Yangming|      4| 90.00|   100.00|   67.00|  85.67|
---------------------------------------------
|  Liping |      1| 78.00|   98.00|  76.00|  84.00|
---------------------------------------------
| Wangling|      2| 66.00|   90.00|   86.00|  80.72|
---------------------------------------------
| Jiangbo |      3| 89.00|  70.00|   76.00|   78.33|
---------------------------------------------
|         |         80.75|   89.50|   76.25|  82.18|
---------------------------------------------
    程序中要谨慎处理以数组名作函数的参数。由于数组名作为数组的首地址,在形参和实参结合时,传递给子程序的就是数组的首地址。形参数组的大小最好不定义,以表示与调用函数的数组保持一致。在定义的结构体内,成员score [3]用于表示计算的平均成绩,也是我们用于排序的依据。我们无法用数组元素进行相互比较,而只能用数组元素的成员score[3]进行比较。在需要交换的时候,用数组元素的整体包括姓名、学号、三科成绩及平均成绩进行交
换。在程序order()函数中,比较采用: arr[j].score[3]>arr[j+1].score[3],而交换则采用:
arr[j] <------> arr[j+1]
打印本文 打印本文  关闭窗口 关闭窗口