结构体数据是一种可以自己定义的数据,通过一道题目来了解结构体数据和一些其他的知识
要求:定义结构体变量,用它表示考生的学号、姓名以及语文、数学、外语成绩。程序可以输入考生的信息和各门课成绩并实现比较(按总分进行高低排序;当总分相同时,依次按语、数、外的顺序排序)
先给出总的代码:
#include<stdio.h>
struct stu_inf
{
char school_number[20];
char name[20];
int chinese_grade;
int math_grade;
int english_grade;
};
int cmp_all(struct stu_inf* p)
{
int first_all = p->chinese_grade + p->math_grade + p->english_grade;
int second_all = (p+1)->chinese_grade + (p+1)->math_grade + (p+1)->english_grade;
if (first_all < second_all)
//当后者总分比前者多时放回1
return 1;
else if (first_all == second_all)
//当两者的总分相等时放回0
return 0;
else
return 2;
}
int cmp_all_kind(struct stu_inf* p)
{
if (p->chinese_grade < (p+1)->chinese_grade)
return 1;
else if (p->chinese_grade == (p+1)->chinese_grade)
{
if (p->math_grade < (p+1)->math_grade)
return 1;
else if (p->math_grade == (p+1)->math_grade)
{
if (p->english_grade < (p+1)->english_grade)
return 1;
else
return 0;
}
else
return 0;
}
else
return 0;
}
void grade_compare(struct stu_inf* p, int len) //按分数高到分数低进行排序
{
int a, b, ret, ret2;
struct stu_inf tmp;
for (a = 0; a < len - 1; a++)
{
for (b = 0; b < len - 1; b++)
{
ret = cmp_all(p + b);
if (ret == 1)
{
tmp = *(p + b);
*(p + b) = *(p + b + 1);
*(p + b + 1) = tmp;
}
if (ret == 0)
{
ret2 = cmp_all_kind(p + b);
if (ret2 == 1)
{
tmp = *(p + b);
*(p + b) = *(p + b + 1);
*(p + b + 1) = tmp;
}
}
}
}
}
int main()
{
int i;
int len, a, b;
struct stu_inf stu[10];
printf("请输入你要比较多少个学生:");
scanf("%d",&a);
for (b = 0; b < a; b++)
{
printf("输入第 %d 个学生的学号:",b+1);
scanf("%s",stu[b].school_number);
printf("输入第 %d 个学生的名字:",b+1);
scanf("%s",stu[b].name);
printf("分别输入第 %d 个学生的语文,数学,英语成绩:",b+1);
scanf("%d,%d,%d",&stu[b].chinese_grade,&stu[b].math_grade,&stu[b].english_grade);
}
len = a;
grade_compare(stu, len);
for (i = 0; i < len; i++)
{
printf("%s ",stu[i].name);
}
return 0;
}接下来是逐个分析:
struct stu_inf //创建结构体
{
char school_number[20];
char name[20];
int chinese_grade;
int math_grade;
int english_grade;
};创建结构体,包含所要表达的信息(学号,名字,各科成绩),定义结构体用的关键字为struct,结构体类型定义后,其和int,char一样为数据类型,而在定义结构体是并不占据空间内存,结构体创建完后要加; ,也可以用typedef对所创建的结构体进行增加别名,如下:
typedef struct stu_inf
{
char school_number[20];
char name[20];
int chinese_grade;
int math_grade;
int english_grade;
} stus;在增加别名名之后可以直接用新的名字来创建变量,如下:
int main()
{
stus studen[10];
return 0;
}这里就使用了别名来创建一个结构体类型的数组
接下来是编写的函数,用于实现学生数组中的成绩比较
int cmp_all(struct stu_inf* p) //用于比较总分
{
int first_all = p->chinese_grade + p->math_grade + p->english_grade;
int second_all = (p+1)->chinese_grade + (p+1)->math_grade + (p+1)->english_grade;
if (first_all < second_all)
//当后者总分比前者多时返回1
return 1;
else if (first_all == second_all)
//当两者的总分相等时放回0
return 0;
else
//如果前者比后者大返回2
return 2;
}
int cmp_all_kind(struct stu_inf* p) //用于比较单科分数
{
if (p->chinese_grade < (p+1)->chinese_grade)
return 1;
else if (p->chinese_grade == (p+1)->chinese_grade)
{
if (p->math_grade < (p+1)->math_grade)
return 1;
else if (p->math_grade == (p+1)->math_grade)
{
if (p->english_grade < (p+1)->english_grade)
return 1;
else
return 0;
}
else
return 0;
}
else
return 0;
}
void grade_compare(struct stu_inf* p, int len) //按分数高到分数低进行排序
{
int a, b, ret, ret2;
struct stu_inf tmp;
for (a = 0; a < len - 1; a++)
{
for (b = 0; b < len - 1; b++)
{
ret = cmp_all(p + b);
if (ret == 1) //总分不同
{
tmp = *(p + b);
*(p + b) = *(p + b + 1);
*(p + b + 1) = tmp;
}
if (ret == 0) //总分相同,开始比较各科的分数
{
ret2 = cmp_all_kind(p + b);
if (ret2 == 1)
{
tmp = *(p + b);
*(p + b) = *(p + b + 1);
*(p + b + 1) = tmp;
}
}
}
}
}由于我们在主函数里写的是结构体数组,传参的时候传了数组名,因此在这些函数中用指针来接收这个值,其中,用指针来访问结构体的方法如下
p->name
//p是所要访问的结构体变量的地址
//->指向所要访问的结构体内部变量
//name是所要访问的变量cmp_all()函数比较了总的成绩,并返回相应的值,由于要求大到小排序,如果后者比前者大则要交换,因此返回1,如果前者比后者大就返回2,以跳过下面的交换,在grade_compare()中实现交换,如果总成绩相等,还要求按照语文,数学,英语各科成绩的比较来进行排序,因此返回0,在grade_compare函数接收到0后再调用cmp_all_kind()函数进行各科的判断,在cmp_all_kind()函数中,使用类似冒泡排序法对结构体数组进行排序。
int main()
{
int i;
int len, a, b;
struct stu_inf stu[10];
printf("请输入你要比较多少个学生:");
scanf("%d",&a);
for (b = 0; b < a; b++)
{
printf("输入第 %d 个学生的学号:",b+1);
scanf("%s",stu[b].school_number);
printf("输入第 %d 个学生的名字:",b+1);
scanf("%s",stu[b].name);
printf("分别输入第 %d 个学生的语文,数学,英语成绩:",b+1);
scanf("%d,%d,%d",&stu[b].chinese_grade,&stu[b].math_grade,&stu[b].english_grade);
}
len = a;
grade_compare(stu, len);
for (i = 0; i < len; i++)
{
printf("%s ",stu[i].name);
}
return 0;
}主函数部分就是简单的调用自己写的函数,大部分的功能都在grade_compare()函数中实现,值得注意的地方是scanf输入不可以如下这样写
scanf("%s,%s",stu[0].school,stu[0].name)
scanf("%s,%s,%d",stu[0].school,stu[0].name,&stu[0].chinese_grade)我觉得是字符串不可以和其他类型一起输入,这样会导致存进去的内容错误,但程序不会警告
可以用这个程序来排列几个学生的成绩
结果按照预期先比较总分,如果总分相等再按照语文数学英语分数来顺序排序。