有关c语言结构体的应用

结构体数据是一种可以自己定义的数据,通过一道题目来了解结构体数据和一些其他的知识

要求:定义结构体变量,用它表示考生的学号、姓名以及语文、数学、外语成绩。程序可以输入考生的信息和各门课成绩并实现比较(按总分进行高低排序;当总分相同时,依次按语、数、外的顺序排序)

先给出总的代码:

#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)

 我觉得是字符串不可以和其他类型一起输入,这样会导致存进去的内容错误,但程序不会警告

可以用这个程序来排列几个学生的成绩

 结果按照预期先比较总分,如果总分相等再按照语文数学英语分数来顺序排序。


版权声明:本文为Ly2020Wj原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。