文章目录
结构体
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,换页输出
}
}
测试数据一(课本)运行结果:
测试数据二运行结果: