[OJ] 成绩单问题

学生数量N占一行每个学生的学号、姓名、三科成绩占一行,空格分开。
输出
各门课的平均成绩 最高分的学生的数据(包括学号、姓名、3门课成绩)
样例输入:
2
1 blue 90 80 70
b clan 80 70 60
样例输出:
85 75 65
1 blue 90 80 70

分析:最高分指的是总分:

#include <stdio.h>
#include <malloc.h>

struct student_info {  //定义结构体,成员变量分别是姓名,学号以及成绩
		
		char s_id[16];   //学号
		char s_name[32]; //姓名
		int s_grades[16]; //成绩
		int s_total[16]; // 存储每个同学的成绩总分
  //warning 这个地方没必要搞个数组存一个就可以了.
};

void input(struct student_info * input);
void dataHandle(struct student_info * p);


int main()
{

	int n; 
	int i;
	int k;
	int best;
	int sum1,sum2,sum3;
	scanf("%d",&n);
	struct student_info *list[100]; //结构体指针数组初始化,


	for (i=0;i<n;i++){
		list[i] = (struct student_info *)malloc(sizeof(struct student_info)*n); 
		//开辟一块块内存地址,并且把首地址给指针list
	}
	
	for (i=0;i < n;i++){  
		input(list[i]);
	}
	
	for (i=0;i < n;i++){  
		dataHandle(list[i]);
	}

	for ( int i=0;i<n;i++){
		sum1 = sum1+list[i]->s_grades[0]; 
		sum2 = sum2+list[i]->s_grades[0];  //逻辑错误,这里应该为s_grades[1];
		sum3 = sum3+list[i]->s_grades[0];  //逻辑错误,这里应该为s_grades[2]
	}
	sum1=sum1/3;  //逻辑错误,应该除以n
	sum2=sum2/3; //逻辑错误,应该除以n
	sum3=sum3/3; //逻辑错误,应该除以n

	//找到最大值
		k=list[0]->s_total[0];
		for (i=0;i < n;i++){  
		
		if ( k< list[i]->s_total[0] ){
			k= list[i]->s_total[0];
			best =k; //记录下成绩最好的同学
      //error: 应该把i给best;
		}
	}

	printf("%s %s %d %d %d",list[k]->s_id,list[k]->s_name,list[k]->s_name[0],
	list[k]->s_name[1],list[k]->s_name[2]);
  //error,这里应该都用list[i]
	for (i=0;i<n;i++)
	free(list[i]);
    return 0;
 }
 
 void input(struct student_info * input){
		scanf("%s%s%d%d%d",input->s_id,input->s_name,&(input->s_grades[0]),
		&(input->s_grades[1]),&(input->s_grades[2]));  
		// intput->s_id指针变量input指向成员s_id的地址
		// input->s_id ==  (*input).s_id ,
		//这个本质是一个地址常量,指向char数组的开头,所以input->s_id是  char *类型的。
 }
 
void dataHandle(struct student_info *p){

	p->s_total[0]=p->s_grades[0]+ p->s_grades[1]+p->s_grades[2];

	//printf("%s %s %d %d %d\n",p[k]->s_id,p[k]->s_name, 
	//p[k]->s_grades[0],p[k]->s_grades[1],p[k]->s_grades[2]);
	
 }

gcc可以编译通过,但是一运行就报错,原因是:

在这里插入图片描述

printf("%s %s %d %d %d",list[k]->s_id,list[k]->s_name,list[k]->s_name[0],
list[k]->s_name[1],list[k]->s_name[2]);

这句代码把字符以%d形式打印出来,报错;

改了之后,代码在编程网站上提交通过,代码如下:

#include <stdio.h>
#include <malloc.h>

struct student_info {  //定义结构体,成员变量分别是姓名,学号以及成绩
		
		char s_id[16];   //学号
		char s_name[32]; //姓名
		int s_grades[16]; //成绩
		int s_total; // 存储每个同学的成绩总分
};

void input(struct student_info * input);
void dataHandle(struct student_info * p);


int main()
{

	int n; 
	int i;
	int k;
	int best=0;
	int sum1=0;
	int sum2=0;
	int sum3=0;
	scanf("%d",&n);
	struct student_info *list[100]; //结构体指针数组初始化,


	for (i=0;i<n;i++){
		list[i] = (struct student_info *)malloc(sizeof(struct student_info)*n); 
		//开辟一块块内存地址,并且把首地址给指针list
	}
	
	for (i=0;i < n;i++){  
		input(list[i]);
	}
	
	for (i=0;i < n;i++){  
		dataHandle(list[i]);
	}

	for ( int i=0;i<n;i++){
		sum1 = sum1+list[i]->s_grades[0];
		sum2 = sum2+list[i]->s_grades[1]; 
		sum3 = sum3+list[i]->s_grades[2];
	}
	sum1=sum1/n;
	sum2=sum2/n;
	sum3=sum3/n;

	//找到最大值
		k=list[0]->s_total;
		for (i=0;i < n;i++){  
		
		if ( k< list[i]->s_total ){
			k= list[i]->s_total;
			best =i; //记录下成绩最好的同学
		}
	}
	printf("%d %d %d\n",sum1,sum2,sum3);
	printf("%s %s %d %d %d\n",list[best]->s_id,list[best]->s_name,
	list[best]->s_grades[0],list[best]->s_grades[1],list[best]->s_grades[2]);

	for (i=0;i<n;i++)
	free(list[i]);
    return 0;
 }
 
 void input(struct student_info * input){
		scanf("%s %s %d %d %d",input->s_id,input->s_name,&(input->s_grades[0]),
		&(input->s_grades[1]),&(input->s_grades[2]));  
		// intput->s_id指针变量input指向成员s_id的地址
		// input->s_id ==  (*input).s_id,这个本质是一个地址常量,指向char数组的开头,
		//所以input->s_id是  char *类型的。
 }
 
void dataHandle(struct student_info *p){

	p->s_total=p->s_grades[0]+ p->s_grades[1]+p->s_grades[2];

 }
### 使用结构体进行成绩统计的方法 在东华大学OJ平台上的题目中,经常涉及到利用C/C++中的`struct`来定义学生信息以及完成相应的成绩处理工作。下面展示如何基于给定的学生数据模型实现简单的成绩统计数据。 #### 定义结构体存储学生信息 为了便于管理和操作多个字段的信息,可以采用结构体的方式来表示单个学生对象: ```c #include <stdio.h> #include <string.h> // 定义student结构体用于保存每位同学的具体情况 struct student { char name[10]; // 存储姓名字符串 int math_score; // 数学分数 int politics_score; // 政治分数 }; ``` 此部分代码展示了基本的结构体声明方式[^2],其中包含了学生的姓名、数学成绩和政治成绩三个属性。 #### 输入并计算总分与平均分 接下来通过循环读取五名学生的具体成绩,并对其进行必要的运算得到每人的总分及平均分: ```c int main() { struct student students[5]; float total_scores[] = {0, 0}; // 初始化两个累加器分别对应两科目的总计得分 printf("请输入五个学生的姓名及其对应的数学和政治成绩:\n"); for (int i = 0; i < 5; ++i){ scanf("%s %d %d", &students[i].name, &students[i].math_score, &students[i].politics_score); // 计算各科目累计分数 total_scores[0] += students[i].math_score; total_scores[1] += students[i].politics_score; } // 输出所有学生的原始成绩 puts("\n--- 所有学生的成绩 ---"); for(int j=0;j<5;++j){ printf("Name:%-8s Math Score=%3d Politics Score=%3d\n", students[j].name, students[j].math_score, students[j].politics_score); } // 显示总体均值 printf("\n--\nMath Average=%.2f\nPolitics Average=%.2f\n", total_scores[0]/5.0, total_scores[1]/5.0); return 0; } ``` 上述程序实现了从标准输入获取五个学生的相关信息,并打印出每个人的详细成绩列表;最后还提供了这两门课的整体平均分作为总结性的输出[^1]。 对于更复杂的应用场景,比如需要动态分配内存或者支持更多种类的成绩录入,则可能需要用到更加高级的技术手段如面向对象编程(OOP),即使用类(class)而非单纯的结构体(structure)[^3]。然而,在大多数基础练习题里,仅依靠结构体就足以满足需求了。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值