C语言 关于结构体相关练习

本练习题目是谭浩强C中的7.14,并做了简单修改。
已知十名学生和其相应的五门课程成绩。(1)求五门课程的各自平均成绩。(2)找出每门课程的最高成绩和其对应的学生姓名.(3)按照第一门课程的成绩从小到大排序。(4)求平均分方差。

typedef struct Student{  //学生结构体 
 char name[32];
 double score[5];
}Student;
int main(int argc, char *argv[])
{
	Student stu[10];
 	Student stutemp;
 	double sum[10]={0}; //初始化,而且int型自动向double型类型转换
 	double avg[10];
 	char array[4];
 	int i,j,k,max,min,temp; //排序和求最大值相关变量
 	double mul=1,cha=0;//求方差相关变量
 	printf("\n-----------------Init----------------\n");//分割线
 
 	printf("姓名\t成绩一\t成绩二\t成绩三\t成绩四\t成绩五\t\n");
 	for(i=0;i<10;i++){   //为了减轻输入繁琐等问题,采取随机数产生姓名和成绩
  		for(k=0;k<4;k++){
   			srand(&stu[i].score[k]);  //随机数种子是数组地址
   			stu[i].name[k]=rand()%26+97;  //取值范围是97~122
  		}
  		stu[i].name[k]='\0';  //这是字符串结束符,表示字符串结束,防止在输出时出现乱码
  		for(j=0;j<5;j++){
   		srand(&stu[i].score[j]);
   		stu[i].score[j]=(double)(rand()%150+1);	//成绩是150分的,并且防止出现零分				
	} 
  	printf("%s\t%3.1lf\t%3.1lf\t%3.1lf\t%3.1lf\t%3.1lf\t\n",stu[i].name,stu	[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4]);
 
}
 printf("\n-----------------AVG----------------\n");//分割线
 printf("功课的成绩:\n");
 for(i=0;i<5;i++){
  	for(j=0;j<10;j++){
   		sum[i]+=stu[j].score[i];
  	}
  avg[i]=sum[i]/10.0;
  printf("第%d门功课平均成绩: %3.1lf\n",i+1,avg[i]);
 }//这里要注意double型是%lf,千万不可写成%d,否则会导致不正确输出,这个问题坑死我了!!!
 
 printf("\n-----------------Sort Way1----------------\n");//分割线
 /**
 	在不改变原有顺序的情况下,选择排序类似的思路是最好的,(当时想了冒泡排序,但是要改变原有顺序,不可取)。
 	但是这里有一个特别容易忽视的问题,就是当学生成绩的最大值恰好是当前的数组元素,那么它和后边的数组元素相比较后,指针max没有改变,max仍然指向j。此时外层循环j+1,这就导致最大值被遗漏,而max则又被赋值给下一个j。
 	解决方案:在内层循环完毕之后,判断max是否与当前外层循环的j相等,如果相等,那么输出相应课程的成绩最大值,并结束当前课程成绩的比较。
 */
 for(i=0;i<5;i++){   //选出每门课程最高成绩和相应姓名(这是个难点)
  	for(j=0;j<10;j++){
   		max=j;
   		for(k=j+1;k<10;k++)
	    		if(stu[max].score[i]<stu[k].score[i])
     			max=k;
   		if(max==j){
    			printf("第%d门课程最高分数是%3.1lf,该学生是%s\n",i+1,stu[max].score[i],stu[max].name);
    			break; 
   		}  
  	}
 } 
 printf("\n---------------------------------\n");//分割线
for(i=0;i<5;i++) {  //这是对上一个方法的改进
//  j=0;
  	max=0;  //表示max下标指的是数组第一个元素
  	for(k=1;k<10;k++){
   		if(stu[max].score[i]<stu[k].score[i])
     		max=k; 
  	}
   printf("第%d门课程最高分数是%3.1lf,该学生是%s\n",i+1,stu[max].score[i],stu[max].name);
}
 printf("\n-----------------Sort Way2 ASC----------------\n");//分割线
 //按照第一门课程成绩排序 
 for(j=0;j<10;j++){   //主要思想是选择排序
  	min=j;
  	for(k=j+1;k<10;k++)
   		if(stu[min].score[0]>stu[k].score[0])
		   min=k;
	stutemp=stu[j];
  	stu[j]=stu[min];
  	stu[min]=stutemp; 
 }
 printf("按照第一门课程成绩排序 :\n");
 printf("姓名\t成绩\n");
 for(i=0;i<10;i++){
  	printf("%s\t%3.1lf\n",stu[i].name,stu[i].score[0]);
 }
 printf("\n---------------------------------\n");//分割线
 for(i=0;i<10;i++)  //这个循环主要是验证经过选择排序后,数组元素的位置变化
  	printf("%s\t%3.1lf\t%3.1lf\t%3.1lf\t%3.1lf\t%3.1lf\t\n",stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4]);
  
  
 printf("\n-----------------平均分方差----------------\n");//分割线
 for(i=0;i<5;i++){
  	for(j=0;j<10;j++){
   		mul+=stu[j].score[i]*stu[j].score[i];
  	}
  cha = mul/10-(avg[i])*(avg[i]);
  mul=0;
  printf("第%d门功课平均分方差: %3.1lf\n",i+1,cha); 
 } 
  
 return 0;
}

//输出结果:
-----------------Init----------------
姓名 成绩一 成绩二 成绩三 成绩四 成绩五
hhhi 130.0 6.0 32.0 59.0 85.0
iijj 65.0 91.0 118.0 144.0 20.0
jkkk 150.0 27.0 53.0 79.0 105.0
llll 86.0 112.0 138.0 14.0 40.0
mmmm 21.0 47.0 73.0 99.0 125.0
nnnn 106.0 132.0 8.0 34.0 60.0
oooo 41.0 67.0 93.0 119.0 145.0
pppp 126.0 2.0 28.0 54.0 81.0
qqqr 61.0 87.0 113.0 140.0 16.0
rrss 146.0 22.0 49.0 75.0 101.0

-----------------AVG----------------
功课的成绩:
第1门功课平均成绩: 93.2
第2门功课平均成绩: 59.3
第3门功课平均成绩: 70.5
第4门功课平均成绩: 81.7
第5门功课平均成绩: 77.8

-----------------Sort Way1----------------
第1门课程最高分数是150.0,该学生是jkkk
第2门课程最高分数是132.0,该学生是nnnn
第3门课程最高分数是138.0,该学生是llll
第4门课程最高分数是144.0,该学生是iijj
第5门课程最高分数是145.0,该学生是oooo

-----------------Sort Way2 ASC----------------
按照第一门课程成绩排序 :
姓名 成绩
mmmm 21.0
oooo 41.0
qqqr 61.0
iijj 65.0
llll 86.0
nnnn 106.0
pppp 126.0
hhhi 130.0
rrss 146.0
jkkk 150.0


mmmm 21.0 47.0 73.0 99.0 125.0
oooo 41.0 67.0 93.0 119.0 145.0
qqqr 61.0 87.0 113.0 140.0 16.0
iijj 65.0 91.0 118.0 144.0 20.0
llll 86.0 112.0 138.0 14.0 40.0
nnnn 106.0 132.0 8.0 34.0 60.0
pppp 126.0 2.0 28.0 54.0 81.0
hhhi 130.0 6.0 32.0 59.0 85.0
rrss 146.0 22.0 49.0 75.0 101.0
jkkk 150.0 27.0 53.0 79.0 105.0

-----------------平均分方差----------------
第1门功课平均分方差: 1843.1
第2门功课平均分方差: 1860.4
第3门功课平均分方差: 1709.5
第4门功课平均分方差: 1716.4
第5门功课平均分方差: 1699.0
请按任意键继续. . .

发布了15 篇原创文章 · 获赞 0 · 访问量 225

猜你喜欢

转载自blog.csdn.net/ren_x_guo/article/details/104827979