厦大2021届小学期C语言作业2【结构体】

结构体

1.定义含年月日的结构体变量,计算改日在本年中是第几天

#include<stdio.h>
int main() {
	struct Date {
		int year;
		int month;
		int day;
	} date;
	scanf("%d%d%d", &date.year, &date.month, &date.day);
	int sum = 0;
	int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	for (int i = 0; i < date.month; i++) {
		sum += a[i];
	}
	sum += date.day;
	if (date.month >= 3) { //第一次没过的原因,要先判断是否超过二月
		if (date.year % 4 == 0) {
			if ((date.year % 400 == 0) || (date.year % 100 != 0)) {
				sum += 1;
			}
		}
	}
	printf("%d", sum);
	return 0;
}

2. 写一个函数days,由主函数将年月日传递给days函数,计算后将总数传回主函数输出

#include<stdio.h>
int days(int year, int month, int day);
int main() {
	struct Date {
		int year;
		int month;
		int day;
	} date;
	scanf("%d%d%d", &date.year, &date.month, &date.day);
	int total = days(date.year, date.month, date.day);
	printf("%d", total);
	return 0;
}
int days(int year, int month, int day) {
	int sum = 0;
	int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	for (int i = 0; i < month; i++) {
		sum += a[i];
	}
	sum += day;
	if (month >= 3) { //第一次没过的原因,要先判断是否超过二月
		if (year % 4 == 0) {
			if ((year % 400 == 0) || (year % 100 != 0)) {
				sum += 1;
			}
		}
	}
	return sum;
}

3. 用结构体数组存储五个学生的数据并编写一个函数print输出

#include<stdio.h>
void print(struct Student stu[5]);
struct Student {
	int num;
	char name[8]={0};
	int score[3] = {0};
} stu[5];
int main() {
	for (int i = 0; i < 5; i++) {
		scanf("%d%s%d%d%d", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
	}
	print(stu);
	return 0;
}
void print(struct Student stu[2]) {
	for (int i = 0; i < 5; i++) {
		printf("%d %s %d %d %d\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
	}
}

4. 在3的基础上,编写一个input输入

#include<stdio.h>
void print(struct Student stu[5]);
void input(struct Student stu[5]);
struct Student {
	int num;
	char name[8]={0};
	int score[3] = {0};
} stu[5];
int main() {
	input(stu);
	print(stu);
	return 0;
}
void print(struct Student stu[5]) {
	for (int i = 0; i < 5; i++) {
		printf("%d %s %d %d %d\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
	}
}
void input(struct Student stu[5]) {
	for (int i = 0; i < 5; i++) {
		scanf("%d%s%d%d%d", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
	}
}

5.计算三门课程总平均成绩,并输出三门课程均分最高的学生的数据

#include<stdio.h>
void print(struct Student stu[]);
void input(struct Student stu[]);
struct Student {
	int num;
	char name[8] = {0};
	int score[3] = {0};
} stu[10];
int main() {
	input(stu);
	print(stu);
	return 0;
}
void print(struct Student stu[5]) {
	float sum = 0, aver = 0, max = -1;
	int p;
	for (int i = 0; i < 10; i++) {
		sum = sum + (stu[i].score[0] + stu[i].score[1]+stu[i].score[2]);
		aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;
		if (aver > max) {
			max = aver;
			p = i;
		}
	}
	printf("%f\n", sum / 30.0); //三门课程总平均成绩
	printf("%d %s %d %d %d", stu[p].num, stu[p].name, stu[p].score[0], stu[p].score[1], stu[p].score[2]);//最高分学生的数据
}
void input(struct Student stu[10]) {
	for (int i = 0; i < 10; i++) {
		scanf("%d%s%d%d%d", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
	}
}

案例一,计算员工工资的对应纳税额,并用文件读写

题目描述:
仔细阅读理解教辅13.1节《案例1 个人所得税计算》的程序、原理、流程、算法等,然后进行以下程序改进、完善:

  • 1、起征点也写入文件中;
  • 2、税率表级数也写入文件中;输入/修改功能;
  • 3、表格中数据统一类型,用数组代替结构体;
  • 4、税率表只存上限,不存下限;
  • 5、另一个文件中存若干人员的工资信息,
  • 6、程序计算每人的纳税额,增加一栏,存文件中
    注:为C语言程序设计谭浩强第五版学习辅导

案例1.1

#include<stdio.h>
#include<process.h>
#include<stdlib.h>
#define SIZE 9
#define NUMBER 3
typedef struct people {
	char name[50] = {0};
	long salary = 0;
} PERSON;
void acceptdata(long tax_list[][4]);
void acceptdata2(PERSON sum[NUMBER]);
int main() {
	long start;
	printf("请输入起征点:\n");
	scanf("%ld", &start);
	FILE *fp1;
	long tax_list[SIZE][4] = {0}; //3.统一数据类型,用数组代替结构体
	if ((fp1 = fopen("TAX.din", "wb")) == NULL) { 
		printf("\ncannot open file\n");
		exit(1);
	}
	acceptdata(tax_list);
	fwrite(&start, sizeof(long), 1, fp1); //1.起征点放入文件头
	for (int i = 0; i < SIZE; i++) { //二维数组写进文件
		fwrite(tax_list[i], sizeof(long), 4, fp1);
	}
	fclose(fp1);
	FILE *fp2;
	PERSON sum[NUMBER];
	if ((fp2 = fopen("PERSON.din", "wb")) == NULL) { //5.另一文件中存若干人员的工资信息
		printf("\ncannot open file\n");
		exit(1);
	}
	acceptdata2(sum);
	if ((fwrite(sum, sizeof(PERSON), NUMBER, fp2)) != NUMBER) { //写入文件
		printf("2.file write error\n");
		exit(1);
	}
	fclose(fp2);
	return 0;
}
void acceptdata(long tax_list[][4]) {//从键盘读入数据
	for (int i = 0; i < SIZE; i++) {
		tax_list[i][0] = i + 1; //级数从1开始。2.税率表级数写入文件
		printf("Please enter data:\n");
		scanf("%ld", &tax_list[i][1]);//上限  4.只存上限
		scanf("%ld", &tax_list[i][2]);//税率
		scanf("%ld", &tax_list[i][3]);//速算扣除数
	}
}
void acceptdata2(PERSON sum[NUMBER]) {//从键盘读入数据
	for (int i = 0; i < NUMBER; i++) {
		printf("Please enter data:\n");
		scanf("%s", sum[i].name);//姓名
		scanf("%ld", &sum[i].salary ); //工资
	}
}

案例1.2

#include<stdio.h>
#include<process.h>
#include<stdlib.h>
#define SIZE 9
#define NUMBER 3
typedef struct people {
	char name[50] = {0};
	long salary = 0;
} PERSON;
PERSON sum[NUMBER];
void disp(long tax_list[][4], PERSON sum[NUMBER], long start);
int main() {
	long start;
	FILE *fp1;
	long tax_list[SIZE][4];//级数,上限,税率,速算扣除数
	if ((fp1 = fopen("TAX.din", "rb")) == NULL) {
		printf("\ncannot open file\n");
		exit(1);
	}
	fread(&start, sizeof(long), 1, fp1);//读取起征税点
	for (int i = 0; i < SIZE; i++) {//存入二维数组
		fread(tax_list[i], sizeof(long), 4, fp1);
	}
	fclose(fp1);

	FILE *fp2;
	if ((fp2 = fopen("PERSON.din", "rb")) == NULL) {
		printf("\ncannot open file\n");
		exit(1);
	}
	if (fread(sum, sizeof(PERSON), NUMBER, fp2) != NUMBER) {//存入结构体
		printf("2.file read error\n");
		exit(1);
	}
	fclose(fp2);
	disp(tax_list, sum, start);
	return 0;
}
void disp(long tax_list[][4], PERSON sum[NUMBER], long start) {
	long tax[NUMBER] = {0};
	for (int i = 0; i < NUMBER; i++) {
		for (int j = 0; j < SIZE; j++) {
			if (sum[i].salary > tax_list[j][1]) {
				tax[i] = (sum[i].salary - start) * tax_list[j][2]/100 - tax_list[j][3];
			}
		}
	}
	for (int i = 0; i < NUMBER; i++)//检查纳税额计算是否正确
		printf("%ld ", tax[i]);
	FILE *fp3;
	if ((fp3 = fopen("PERSON.din", "w+b")) == NULL) {
		printf("3.file read error\n");
		exit(1);
	}
	if ((fwrite(tax, sizeof(long), NUMBER, fp3)) != NUMBER) {//6.纳税额存入文件
		printf("4.file write error\n");
		exit(1);
	}
	fclose(fp3);
}

测试数据:

1600
0 5 0
500 10 25
2000 15 125
5000 20 375
20000 25 1375
40000 30 3375
60000 35 6375
80000 40 10375
100000 45 15375
LIMING
8000
XIAOHONG
3000

在这里插入图片描述
在这里插入图片描述

案例二,按公式计算学生的总评成绩,每科平均分、标准差,并打印。计算期末成绩的最高最低分,生成期末成绩直方图

题目描述:
仔细阅读理解教辅13.2节《案例2 学生试卷分数统计》的程序、原理、流程、算法等,然后进行以下程序改进、完善:

  • 1、输入程序、调试程序,使程序能正确运行。
  • 2、查出并修正程序中的错误。
  • 3、改进、完善程序中你认为写得不好的地方。
  • 4、增加、完善程序功能:
  • ​ 1) 输入数据及统计数据存入磁盘文件中,
  • ​ 2) 平时、总评成绩也统计、算标准差,
  • ​ 3)增加期中成绩,总评成绩保留1位小数…
  • 5、按成绩排序(多关键字)
  • 6、思考: 只有1~2位小数的浮点数的整数算法。

案例2

#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<math.h>
#define SIZE 5

typedef struct student {
	int number;
	int score[4];                          //平时、期中、期末、总评
} STUDENT;
int m;//全局声明
int accept_data(STUDENT stu[], int grade[]);
void show_data(STUDENT stu[], int sum, int grade[]);

void draw(int grade[]);
void count(int *max, int *min, double *pass, double ave[], double f[], STUDENT stu[], int sum);
void show_data2(int max, int min, double pass, double ave[], double f[]);
void sort_print(STUDENT stu[], int sum);
int cmp(const void *a, const void *b, int m);
int main() {
	STUDENT stu[SIZE];
	int sum, max, min; //总人数,期末成绩最大最小值
	int grade[11] = {0};//总评成绩10分数段统计
	double ave[4] = {0}, f[4] = {0}	, pass = 0; //求平均成绩、标准差用,pass:期末成绩合格率
	sum = accept_data(stu, grade);                   //输入
	show_data(stu, sum, grade);                         //显示
	draw(grade);                                            //画期末成绩直方图
	count(&max, &min, &pass, ave, f, stu, sum); //统算
	show_data2(max, min, pass, ave, f);            //显示


	while (~scanf("%d", &m)) {
		char s[4][10] = {"平时", "期中", "期末", "总评"};
		printf("按照%s成绩排序\n", s[m]);
		sort_print(stu, sum);
	}
	return 0;
}

int accept_data(STUDENT stu[], int grade[]) {
	int i = 0, sum, temp = 0, a1 = 0, a2 = 0, a3 = 0;

	printf("请输入计算总评成绩时使用平时、期中、期末成绩的比例,用整数表示");
	scanf("%d%d%d", &a1, &a2, &a3);
	while (i < SIZE) { //输入不到size就会跳出
		printf("\n请输入学号:");
		scanf("%d", &stu[i].number);
		if (stu[i].number == -1) {//-1表示结束
			sum = i;
			break;
		}
		printf("\n请依次输入学生的平时成绩、期中成绩、期末成绩:");
		int flag = 1;
		while (flag == 1) {
			scanf("%d%d%d", &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
			if (stu[i].score[0] <= 100 && stu[i].score[0] >= 0 && stu[i].score[1] <= 100 && stu[i].score[1] >= 0 && stu[i].score[2] <= 100 && stu[i].score[2] >= 0)
				flag = 0;
			else
				printf("\n\007错误数据!请再次输入学生的平时成绩、期中成绩、期末成绩:");
		}
		temp = (int)(1.0 * a1 / 100 * stu[i].score[0] + 1.0 * a2 / 100 * stu[i].score[1] + 1.0 * a3 / 100 * stu[i].score[2]);
		stu[i].score[3] = (float)((int)((temp + 0.5) * 10)) / 10.0; //总评存入数组,保留一位小数

		temp = (stu[i].score[2]) / 10;//错误1.
		//统计期末考十个分数段人数
		if (temp == 10)
			grade[10] ++;
		else
			grade[temp + 1] ++;
		++ i;
	}
	return sum;

}
void show_data(STUDENT stu[], int sum, int grade[]) {
	for (int i = 0; i < sum; i++) {
		printf("%4d", stu[i].number);
		for (int j = 0; j < 4; j++) {
			printf("%4d", stu[i].score[j]);
		}
		putchar('\n');//2.改\n为\f,换页输出
	}
	for (int i = 1; i <= 10; i++) {
		printf("%d ", grade[i]);
	}
	FILE *fp1;
	if ((fp1 = fopen("IN.bin", "wb")) == NULL) {
		printf("\n1.cannot open file\n");
		exit(1);
	}
	if ((fwrite(stu, sizeof(STUDENT), sum, fp1)) != sum) {
		printf("1.file write error\1");
		exit(1);
	}
	fclose(fp1);

}
void count(int *max, int *min, double * pass, double ave[], double f[], STUDENT stu[], int sum) {
	int  p_sum = 0;//p_sum--期末成绩及格人数
	int total[4] = {0}; //4.定义时直接初始化
	*max = *min = stu[0].score[2];
	if (stu[0].score[2] >= 60)
		p_sum++;
	for (int i = 1; i < sum; i++) {//i从1开始,找出期末成绩的最大最小值
		if ((stu[i].score[2]) > *max)
			*max = stu[i].score[2];
		if ((stu[i].score[2]) < *min)
			*min = stu[i].score[2];
		if (stu[i].score[2] >= 60)
			p_sum++;
	}
	*pass = (1.0 * p_sum / (double)sum) * 100.0;//期末成绩及格率(去%表示)3.改100->1,统一格式
	for (int j = 0; j < 4; j++) {
		for (int i = 0; i < sum; i++) {
			total[j] += stu[i].score[j];//5.改成+=,更简洁易读
		}
		ave[j] = (double)total[j] / (double)sum;//6.可省略浪费的for循环
	}

	for (int j = 0; j < 4; j++) {
		for (int i = 0; i < sum; i++) {
			double temp = (double)stu[i].score[j] - ave[j];
			f[j] += temp * temp;//8.改为+=
		}
		f[j] = sqrt(f[j] / (double)sum); //9.fabs可省,temp*temp恒为正
	}
}
void show_data2(int max, int min, double pass, double ave[], double f[]) {
	char str1[4][20] = {"平时成绩平均分", "期中成绩平均分", "期末成绩平均分", "总评成绩平均分"};
	char str2[4][20] = {"平时成绩标准差", "期中成绩标准差", "期末成绩标准差", "总评成绩标准差"};
	printf("\n期末成绩及格率=%6.2f %%期末最高分=%d 期末最低分=%d\n", pass, max, min);
	for (int j = 0; j < 4; j++) {
		printf("\n%s=%6.2f \n%s=%6.2f\n", str1[j], ave[j], str2[j], f[j]);
	}
	FILE *fp2;
	if ((fp2 = fopen("OUT.bin", "wb")) == NULL) {
		printf("\n2.cannot open file\n");
		exit(1);
	}
	fwrite(str1, sizeof(str1[0]), 4, fp2);
	fwrite(ave, sizeof(double), 4, fp2);
	fwrite(str2, sizeof(str2[0]), 4, fp2);
	fwrite(f, sizeof(double), 4, fp2);
	fclose(fp2);
}
void draw(int grade[]) {
	int   max = -0x3f3f3f,	k = 1;
	char screen[22][42] = {0};
	printf("\n模拟期末考成绩直方图\n");

	for (int i = 1; i <= 10; i++) {
		if (grade[i] > max)
			max = grade[i];
		grade[i] = (int)(20.0 * grade[i] / max + 0.5);//最多人数对应y=20
	}

	for (int i = 0; i <= 40; i++) {
		screen[21][i] = '-';
	}
	screen[21][41] = 'X';
	screen[0][0] = 'Y';
	for (int i = 1; i <= 20; i++)
		screen[i][0] = '|';

	for (int x = 1; x <= 10; x++, k += 4) {
		int temp = grade[x];
		if (temp != 0) {
			for (int i = 1; i <= temp; i++) {
				for (int j = 1; j <= 4; j++) {
					screen[20 - i + 1][j + k] = '*';
				}
			}
		}
	}
	for (int i = 0; i <= 21; i++) {
		for (int j = 0; j <= 41; j++)
			if (screen[i][j] != 0)
				printf("%c", screen[i][j]);
			else
				printf(" ");
		printf("\n");
	}
	printf(" 0 10 20 30 40 50 60 70 80 90 100\n");
	getch();
}
int cmp(const void *a, const void *b) {
	STUDENT *aa = (STUDENT*)a;
	STUDENT *bb = (STUDENT*)b;
	return (aa->score[m] < bb->score[m] ? 1 : -1);
}
void sort_print(STUDENT stu[], int sum) {
	qsort(stu, sum, sizeof(STUDENT), cmp);
	for (int i = 0; i < sum; i++) {
		printf("%4d", stu[i].number);
		for (int j = 0; j < 4; j++) {
			printf("%4d", stu[i].score[j]);
		}
		putchar('\n');//2.改\n为\f,换页输出
	}
}

测试数据一(课本)运行结果:

在这里插入图片描述

测试数据二运行结果:

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快苏排序OAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值