本題要求編寫程序,根據輸入學生的成績,統計並輸出學生的平均成績、最高成績和最低成績。建議使用動態內存分配來實現。
輸入格式:
輸入第一行首先給出一個正整數N,表示學生的個數。接下來一行給出N個學生的成績,數字間以空格分隔。
輸出格式:
按照以下格式輸出:
average = 平均成績
max = 最高成績
min = 最低成績
結果均保留兩位小數。
輸入樣例:
3
85 90 95
輸出樣例:
average = 90.00
max = 95.00
min = 85.00
編程思路:根據學生人數,首先創建所需節點數量的鏈表,然後依次錄入學生成績,處理成績(求平均、最大、最小值),輸出
拓展:1、學生信息(學號、姓名、成績、地址)
struct student //定義結構體
{
char name[20];
double num;
int score; //成績 原題只保留這個就可以
char add[40];
struct student *next;
} ;
//原題修改:
//輸入函數裏面
scanf("%d",&q->score);
//去掉 main()中
p_list();函數調用
2、輸出學生信息表
3、輸出成績統計結果
截圖及代碼:
26
20191001 測試_1 98 中國.北京.dizhi_1
20191002 測試_2 78 中國.北京.dizhi_2
20191003 測試_3 84 中國.北京.dizhi_3
20191004 測試_4 93 中國.北京.dizhi_4
20191005 測試_5 71 中國.北京.dizhi_5
20191006 測試_6 70 中國.北京.dizhi_6
20191007 測試_7 71 中國.北京.dizhi_7
20191008 測試_8 89 中國.北京.dizhi_8
20191009 測試_9 95 中國.北京.dizhi_9
20191010 測試_10 86 中國.北京.dizhi_10
20191011 測試_11 88 中國.北京.dizhi_11
20191012 測試_12 81 中國.北京.dizhi_12
20191013 測試_13 85 中國.北京.dizhi_13
20191014 測試_14 71 中國.北京.dizhi_14
20191015 測試_15 79 中國.北京.dizhi_15
20191016 測試_16 96 中國.北京.dizhi_16
20191017 測試_17 81 中國.北京.dizhi_17
20191018 測試_18 83 中國.北京.dizhi_18
20191019 測試_19 93 中國.北京.dizhi_19
20191020 測試_20 80 中國.北京.dizhi_20
20191021 測試_21 84 中國.北京.dizhi_21
20191022 測試_22 87 中國.北京.dizhi_22
20191023 測試_23 93 中國.北京.dizhi_23
20191024 測試_24 72 中國.北京.dizhi_24
20191025 測試_25 95 中國.北京.dizhi_25
20191026 測試_26 88 中國.北京.dizhi_26
輸入部分:
輸出部分:
代碼如下:
#include "stdio.h"
#include "stdlib.h"
struct student //定義結構體
{
char name[20];
double num;
double score; //成績
char add[40];
struct student *next;
} ;
/*創建鏈表*/
void creact_s(struct student *head , int n)
{
int i;
struct student *q;
q=head;
for(i=0;i<n;i++) //循環 創建所需數量的鏈表
{
struct student *p;//創建頭指針
if((p=(struct student *)malloc(sizeof(struct student)))==NULL)
{
printf("Sorry 分配內存失敗......\n");
exit(0);
}
q->next=p;
p->next=NULL;
q=p;
}
}
/*輸入數據*/
void input_s(struct student *head , int n)
{
int i;
struct student *q;
q=head->next;
printf("請依次輸入 %d 名學生的信息:\n",n);
printf("\n學號\t姓名\t成績\t地址\n\n");
for(i=0;i<n;i++)
{
scanf("%lf%s%lf%s",&q->num,&q->name,&q->score,&q->add);
q=q->next;
}
}
/*統計學生成績*/
void stat_s(struct student *head , int n, double *p)
{
int i;
double max,min,sum=0;//sum 成績求和
struct student *q;
q=head->next;//指向第一名學生
max=q->score;//成績最大值 初始化
min=q->score;//成績最大值 初始化
for(i=0;i<n;i++) //遍歷鏈表
{
sum+=q->score;
if(max<q->score)
max=q->score;
if(min>q->score)
min=q->score;
q=q->next;
}
/*統計結果存儲到指定數組*/
p[0]=sum/(double)n;
p[1]=max;
p[2]=min;
}
/*輸出學生成績*/
void output_s(double *p)
{
printf("\n成績統計結果如下:\n\n");
printf("average = %.2lf\n",p[0]);
printf("max = %.2lf\n",p[1]);
printf("min = %.2lf\n",p[2]);
printf("\n");
}
void aoutput_s(struct student *head , int n)
{
int i;
struct student *q;
q=head->next;
//printf("\n\t學號\t 姓名\t成績\t\t地址\n\n");
printf(" ——————————————————————————\n");
for(i=0;i<n;i++)
{
printf("| %-9.0lf| %-8s| %-4.2lf| %-21s |\n",q->num,q->name,q->score,q->add);
printf(" ——————————————————————————\n");
q=q->next;
}
}
/*打印表頭*/
void p_list()
{
int i;
char list_sheet[4][8]={{"學號"},{"姓名"},{"成績"},{"地址"}};
char *p[4];
for(i=0;i<4;i++)
p[i]=list_sheet[i];
printf("\n\n %-10s%-10s%-12s%s\n",p[0],p[1],p[2],p[3]);
}
/*主函數*/
int main()
{
int N;
double achievement[3];
printf("請輸入學生人數: ");
scanf("%d",&N);
/*創建學生鏈表*/
struct student *head=NULL;//創建頭指針
head=(struct student *)malloc(sizeof(struct student));
creact_s(head,N);
input_s(head,N);
stat_s(head,N,&achievement[0]);
p_list();
aoutput_s(head,N);
output_s(&achievement[0]);
system("pause");
}
問題及解決方案:
本題中計算學生成績的階段,遍歷鏈表,最後一個節點的成績統計會有幾種情況,供參考:
case 1:參數傳遞帶學生人數,用 for()循環遍歷鏈表 (個人認為比較簡單的方法)
case 2:參數傳遞不帶學生人數,用 while ()循環遍歷鏈表,
會出現最後一個節點無法統計在內的情況,
兩種解決方法
方法一:while()循環之後,單獨處理 最後一個節點的成績(已經在上面代碼中注視掉的部分)
方法二:在創建鏈表的時候,多創建一個節點;
這裏也有兩種情況供選擇:
1、創建鏈表節點的同時,對節點成員初始化,如本題 可在創建鏈表時 對成員初始化 q->score=0;
2、對結構體初始化;我們暫且稱之為“定義初始化”,定義結構體時(後)直接初始化,使得以後創建的結構體全都是初始化的;
可能比較繞,方法待網友自行查找吧!(我還沒搞透,希望大神指點)