第6章 统计成绩(数组用法)

 

第六章 统计成绩

小故事:

话说逸凡逃掉了第6周星期三的课,班主任还是发觉了。期中考试后,班主任找来逸凡,没有批评,只是说帮他统计成绩。逸凡拿到一堆试卷,赶紧统计全班45人的平均分。一会儿,班主任又叫逸凡统计各个分数段的人数以及各分数段的比例。逸凡又将试卷重新翻开,一个一个地统计各个分数段的人数。

 

一、初次接触

前面,我们使用变量来存储数据。由于逸凡要统计全班同学的平均分,所以不可能定义那么多不同的变量来存储学生成绩。幸运的是,C语言提供了数组类型。下面,我们来学习逸凡如何完成统计平均分的。

1:统计平均分源程序:

#include<stdio.h>

#define Max_N 100

int main()

{

       int Score[Max_N];

       int i;

       int n;

 

       float TotalScore=0;

    float Average;

      

       printf("请输入考生人数n(1-%d):/n",Max_N);

       scanf("%d",&n);

/*判断n的大小*/

       if(n>Max_N || n<1)

       {

              printf("n太大或太小/n");

        return -1;

       }

    /*计算平均成绩*/

       printf("请输入%d个同学成绩:/n",n);

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

       {

              scanf("%d",&Score[i]);

              TotalScore+=Score[i];

       }

 

       Average=TotalScore/n;

       printf("全班同学平均分:%4.1f/n",Average);

    return 0;

}

程序运行结果:为了方便演示运行结果,这里输入10个同学成绩,计算平均分。结果如下:

 

程序说明:(1)在主函数main()头部,用“define”定义了处理学生成绩的最多人数(可以修改);(2)从键盘输入实际处理的学生人数n;(3)输出平均成绩时,使用了精度控制格式“%4.1f”,指定输出宽度为4,精度为1

二、本章知识点

前面,我们使用变量来存储数据。假如要表示一个由3个元素所构成的向量,程序中可以定义三个变量a1a2a3来分别表示该向量的3个元素。假如有100个元素,是不是定义100个变量呢?显然,这样处理很不方便。为此,C语言提供了一种数据类型——数组类型。所谓数组,就是把具有相同类型的若干变量按有序的形式组织起来。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构体数组等各种数组。这里先介绍数值数组。

1.一维数组的定义和引用

1)一维数组的定义

在C语言中使用数组必须先进行定义,这样才能将数组元素存储到内存地址中。

一维数组的定义格式为:

类型说明符 数组名 [常量表达式]

int Score[Max_N];

格式说明:(1)类型说明符是任一种基本数据类型或构造数据类型,常见的有intfloatchar等等,表示数组中所有元素都是该类型;(2)数组名是用户定义的数组标识符,比如Score[Max_N],其数组名是Score;(3)方括号中的常量表达式表示数据元素的个数,也称为数组的长度。

注意事项:(1)不能在方括号中用变量来表示元素的个数,必须在定义数组时明确数组长度。例如,可以通过define来定义数组长度,也可以直接定义为int Score[100]。(2)数组元素下标从0开始计算。例如,定义int Score[6],表示Score数组有6个整型元素,分别为Score[0], Score[1], Score[2], Score[3], Score[4], Score[5]

2)一维数组的引用

数组元素是组成数组的基本单元。数组元素也是一种变量,其使用方法为数组名后跟一个下标。下标表示了元素在数组中的顺序号。

数组元素的一般格式为:

数组名[下标]

 Score[5]   获取数组中第6个元素

注意事项:(1)必须先定义数组,才能使用下标变量。在C语言中只能逐个地使用下标变量,而不能一次引用整个数组。2)下标变量只能为整型常量,且不能超过数组长度。

3)一维数组的初始化

给数组赋值的方法可以利用赋值语句逐个对数组元素进行赋值,还可采用初始化赋值和动态赋值的方法。

1)数组初始化赋值

数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的,这样可以减少运行时间,提高效率。

初始化赋值一般格式为:

 类型说明符 数组名[常量表达式]={值,值……}

int Score[5]={80,90,100,78,93};

格式说明:在{ }中的各数据值即为各元素的初值,各值之间用逗号间隔。

注意事项:

1)可以只给部分元素赋初值。当{ }中值的个数少于元素个数时,只给前面部分元素赋值。

例如:int Score[10]={80,91,72,93,64},表示只给Score[0]Score[4]5个元素赋值,而后5个元素自动赋0

2)只能给元素逐个赋值,不能给数组整体赋值。

3)给全部元素赋值,则在数组说明中,可以不给出数组元素的个数。

例如:int Score[5]={ 80,91,72,93,64};

可写为:int Score[]={80,91,72,93,64};

2:统计各分数段比例的源程序如下:

#include<stdio.h>

#define Max_N 100

int main()

{

       int Score[Max_N];

       int i;

       int n;

    int k;

       int num[11];  /*存放各分数段人数*/

       int FailedNum=0;/*不及格人数*/

       printf("请输入考生人数n(1-%d):/n",Max_N);

       scanf("%d",&n);

    /*判断n的大小*/

       if(n>Max_N || n<1)

       {

              printf("n太大或太小/n");

        return -1;

       }

    /*输入学生成绩*/

       printf("请输入%d个同学成绩:/n",n);

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

       {

              scanf("%d",&Score[i]);       

       }

    /*必须进行数组初始化,也可在定义时初始化*/

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

              num[i]=0;

       /*进行分数段统计*/

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

       {

       k=Score[i]/10;

          num[k]++;         

       }

    /*累加不及格人数*/

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

              FailedNum+=num[i];

    /*输出各分数段的人数及所占百分比*/

       printf("全班不及格(0-59)人数为%d,%4.1f%%/n",FailedNum,FailedNum*100.0/n);

       /*重复任务尽量使用循环结构*/

       for(i=6;i<=9;i++)

              printf("全班%d-%d人数为%d,%4.1f%%/n",i*10,i*10+9,num[i], num[i]*100.0/n);

       printf("全班100分人数为%d,%4.1f%%/n",num[10],num[10]*100.0/n);

    return 0;

}

程序运行结果:为了方便演示运行结果,这里输入6个同学成绩,计算各分数段及百分比。

 

程序说明:(1)将成绩划分为11个等份:0-10,所以用成绩除以10。(2)输出百分比时,需要将整数转化为实型,参与运算,程序中采用乘以100.0,输出“%”时,需要在格式控制符中使用“%%”。

2.二维数组的定义和引用

在实际问题中有很多量是二维的或多维的,因此C语言允许构造多维数组。多维数组元素有多个下标,以标识它在数组中的位置,所以也称为多下标变量。这里只介绍二维数组,多维数组可由二维数组类推而得到。

1)二维数组定义

二维数组一般格式是:

类型说明符 数组名[常量表达式1][常量表达式2]

int Score[45][8];

格式说明:(1)格式中常量表达式1表示第一维下标的长度,常量表达式2 表示第二维下标的长度。例如,二维数组Score中第一个下标值为45,表示45个学生;第二个下标值为8,表示每个学生有8门课成绩。(2)二维数组元素下标也是从0开始计算。例如,二维数组Score中元素分别为Score[0][0]Score[0][1]……Score[0][7]Score[1][0]……Score[1][7]……Score[44][0]Score[44][1]……Score[44][7]

2)二维数组初始化

二维数组初始化也是在类型说明时给各下标变量赋以初值。二维数组可按行分段赋值,也可按行连续赋值。

注意事项:

1)可以只对部分元素赋初值,未赋初值的元素自动取0值;

2)若对全部元素赋初值,则第一维的长度可以不给出。

例如:

int Score[3][3]={81,72,93,64,55,86,77,88,99};

可以写为:

int Score[][3]={81,72,93,64,55,86,77,88,99};

3)二维数组可以看作是由一维数组的嵌套而构成的:它的元素又是一个一维数组。

例如,数组Score可以看作是一个一维数组,它有3个学生的成绩,Score[0]Score[1]Score[2],每个学生的成绩又是一个包含3门课程成绩的一维数组。这样,可以将Score[0]Score[1]Score[2]看怍是三个一维数组的名字。上述定义的二维数组可以理解为定义了三个一维数组,即相当于定义为:

    int Score[0][3],Score[1][3],Score[1][3];

因此,对于二维数组初始化赋值一些注意事项可以参照一维数组。

3 一个学习小组有5个人,每个人有3门课的考试成绩。问各门课程的最高分是谁?

 

大学数学

大学英语

大学语文

赵一

80

61

87

钱二

75

65

63

孙三

92

71

70

李四

89

78

76

王五

90

72

72

输出各门课程最高分的学生名单源程序:

#include<stdio.h>

#define Max_StuNum 100

#define Max_LessonNum 10

int main()

{

    int Score[Max_StuNum][Max_LessonNum];

    int StuNum=0;

    int LessonNum=0;

    int MaxScoreStuNo[Max_LessonNum];

    int i,j;

    int tempMaxScore=0;

    int tempStuNo=0;

    char StuName[Max_StuNum][8];

    char LessonName[Max_LessonNum][100];

    /*输入学生人数和课程门数*/

    printf("请输入学生人数(1-%d):/n",Max_StuNum);

    scanf("%d",&StuNum);

    /*判断n的大小*/

    if(StuNum > Max_StuNum || StuNum <1)

    {

        printf("学生人数太多或太少/n");

        return -1;

    }

    printf("请输入课程门数(1-%d):/n",Max_LessonNum);

    scanf("%d",&LessonNum);

    if(LessonNum>Max_LessonNum || LessonNum<1)

    {

        printf("课程门数太多或太少/n");

        return -1;

    }

    /*输入学生姓名和课程名称*/

    printf("输入%d个学生的姓名:/n",StuNum);

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

        scanf("%s",StuName[i]);

    printf("输入%d门课程名:/n",LessonNum);

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

        scanf("%s",LessonName[i]);

    /*输入每个学生的每门课程成绩*/

printf("请输入%d个学生成绩/n",StuNum);

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

    {   printf("请输入%s%d门成绩:/n",StuName[i],LessonNum);

        for(j=0;j<LessonNum;j++)

            scanf("%d",&Score[i][j]);

    }

    /*保存各门课程最高分学生的序号*/

    for(j=0;j<LessonNum;j++)

    {

        tempMaxScore=0;/*循环一次需要重新赋值*/

        tempStuNo=0; /*循环一次需要重新赋值*/

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

        {

            if(Score[i][j]>tempMaxScore)

            {

                tempMaxScore=Score[i][j];

                tempStuNo=i;

            }

        }

        MaxScoreStuNo[j]=tempStuNo;

    }

    for(j=0;j<LessonNum;j++)

       printf("%s的最高分是%s/n",LessonName[j], StuName[MaxScoreStuNo[j]]);

    return 0;

}

程序运行结果:输入了5个学生的姓名和3门课程名称,运行结果如下:

 

程序说明:(1)将每次临时最高分保存在变量tempMaxScore,并记下临时最高分学生的序号tempStuNo,一门课程处理结束时将最高学生序号保存在一维数组MaxScoreStuNo中。(2)处理完一门课程后,需要对两个临时变量tempMaxScoretempStuNo重新赋0值,否则上次保存的结果会造成错误。

三、模仿学习

4 实现矩阵乘法C=A*B

解题思路:(1)三个矩阵可以用二维数组来存储,定义为:

int A_Matrix[M][N],B_Matrix[N][P],C_Matrix[M][P];

矩阵相乘公式为: ,其中i=0,……,M-1j=0,……,P-1

 

2)本程序预先定义了最大为100×100的矩阵,具体矩阵相乘时要输入实际的行和列。这里没有比较A矩阵的列和B矩阵的行是否相等,而是直接将A矩阵的列值作为B矩阵的行值。

源程序如下:

#include <stdio.h>

#define M 100

#define N 100

#define P 100

 

int main()

{

    int i,j,k;

    int A_Matrix[M][N],B_Matrix[N][P],C_Matrix[M][P];

    int New_M,New_N,New_P;

    printf("请输入A矩阵行(1-%d)和列(1-%d):/n",M,N);

    scanf("%d %d",&New_M,&New_N);

    if( New_M<1 || New_M>100 || New_N<1 || New_N>100)

    {

        printf("A矩阵行和列太小或太大/n");

        return -1;

    }

    printf("请输入B矩阵列(1-%d):/n",P);

    scanf("%d",&New_P);

    if( New_P<1 || New_P>100)

    {

        printf("B矩阵列太小或太大/n");

        return -1;

    }

printf("请输入%d%dA矩阵和%d%dB矩阵:/n",New_M,New_N,New_N, New_P);

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

    {

        printf("输入A矩阵第%d行的%d个数据:",i+1,New_N);

        for(j=0;j<New_N;j++)

            scanf("%d",&A_Matrix[i][j]);

    }

 

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

    {

        printf("输入B矩阵第%d%d个数据:",i+1,New_P);

        for(j=0;j<New_P;j++)

            scanf("%d",&B_Matrix[i][j]);

    }

 

    printf("输入的A矩阵为:/n");

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

    {

        for(j=0;j<New_N;j++)

            printf("%5d",A_Matrix[i][j]);

        printf("/n");

    }

    printf("输入的B矩阵为:/n");

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

    { 

        for(j=0;j<New_P;j++)

            printf("%5d",B_Matrix[i][j]);

        printf("/n");

    }

 

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

       for(j=0;j<New_P;j++)

       {   C_Matrix[i][j]=0;

           for(k=0;k<New_N;k++)

              C_Matrix[i][j]+=A_Matrix[i][k]*B_Matrix[k][j];

       }

 

    printf("A*B矩阵的乘积C:/n");

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

    {  for(j=0;j<New_P;j++)

       printf("%5d",C_Matrix[i][j]);

       printf("/n");

    }

return 0;

}

程序运行结果:

 

程序说明:(1)在使用C_Matrix数组时,需要初始化。(2)用scanf函数输入数据时,如果输入太多的数据,多余的数据会传给后面的变量,所以输入数据时尽量按要求输入。

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值