C程序设计(第五版)第九章结构体习题答案(手写系统版)

C程序设计(第五版)第八章(指针)习题答案(手写系统版)

全部题目以函数的方式存放,在主函数中输入题号即可运行
以下代码均经过上机测试(编译器为Visual Studio2017)
欢迎相互交流学习!!

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<typeinfo>   
void t1();
void t2();
void t3();
void t4();
void t5();
void t6();
void t7();
void t10();
void t11();
void t12();
int isLeapYear(int year);
int days(int year, int month, int day);
//t1、t2用
typedef struct  {
	int year;
	int month;
	int day;
}Date;
//t3用
typedef struct  {
	int num;
	char name[20];
	int score[3];
}Record;
//t6用
struct Person {
	int num;
	int live;
	struct Person* next;
};

//t7 t8 t9用
struct Student {
	int num;
	int age;
	float score;
	char name[20];
	char gender;
	struct Student* next;
};


void print(Record* p, int n);
void input(Record *p, int n);
Person* createPeople(int n);
void printPeople(Person *head);
void exit(Person *p, int sum);
void inputStudent(Student *stu);
Student* createStudent();
void printStudent(Student *stu);
Student* del(Student *head, int num);
Student *insert(Student *head, int num);
Student *insertByScore(Student *head, Student *add);
Student* mergeStudents(Student *p1, Student *p2);
Student* delStudents(Student *a, Student *b);
Student* del2(Student *head, int age);
const int personSize = sizeof(Person);
const int studentSize = sizeof(Student);

int main() {
	/*
		在各个函数的输入环节后可加上以下语句,避免影响后来的输入流
		//清空缓存区 避免用户输入多余的字符影响后续操作
		int c;
		while ((c = getchar()) != '\n' && c != EOF);
	*/
	int num = 0;
	int c;
	while (true)
	{
		printf("查看第几题?\n");
		scanf("%d", &num);
		if (num < 1 || num>12) {
			printf("无此题%d,请重新输入\n", num);
			//清空缓存区非法输入
			while ((c = getchar()) != '\n' && c != EOF);
			continue;
		}
		//读入回车键 清空缓存区 //Bug:需要输入字符串时少输入了一行
		getchar();

		void(*nums[12])() = {t1,t2,t3,t4,t5,t6,t7,t7,t7,t10,t11,t12};
		void(*num_point)() = *(nums + num - 1);
		num_point();
		//num置0 //Bug: 下一次输入非数字类型非法字符会进入上一个调用的函数,且缓存区(非法字符)会进入函数调用中
		num = 0;
	}
	
	
	
	system("pause");

}

static void t1() {
	
	Date date;
	int sum = 0;
	printf("please input the year,month,day\n");
	scanf("%d,%d,%d", &date.year, &date.month, &date.day);
	for (int i = 1; i <=date.month; i++) {

		if (i == 1) {
			continue;
		}
		else
		{
			//大月+1
			if (i == 2 || i == 4 || i == 6 || i == 8 || i == 9 || i == 11) {
				sum += 31;
				continue;
			}

			if (i == 3) {
				if (isLeapYear(date.year)) {
					sum += 29;
					continue;
				}
				else {
					sum += 28;
					continue;
				}
			}

			else {
				sum += 30;
				continue;
			}
			
		}
	}
	sum += date.day;

	printf("is The %dst day\n",sum);
	
}

//t1用
static int isLeapYear(int year) {
	return !(year % 4) && year % 100 || !(year % 400);
}

static void t2() {
	Date date;
	printf("please input the year,month,day\n");
	scanf("%d,%d,%d", &date.year, &date.month, &date.day);
	printf("is The %dst day\n", days(date.year,date.month,date.day));
}

//t2用
static int days(int year, int month, int day) {
	int sum = 0;
	for (int i = 1; i <= month; i++) {

		if (i == 1) {
			continue;
		}
		else
		{
			//大月+1
			if (i == 2 || i == 4 || i == 6 || i == 8 || i == 9 || i == 11) {
				sum += 31;
				continue;
			}

			if (i == 3) {
				if (isLeapYear(year)) {
					sum += 29;
					continue;
				}
				else {
					sum += 28;
					continue;
				}
			}

			else {
				sum += 30;
				continue;
			}

		}
	}
	sum += day;
	return sum;
}

static void t3() {
	Record records[5];
	for (int i = 0; i < 5; i++) {
		printf("input the num:\n");
		scanf("%d", &records[i].num);
		printf("input the name:\n");
		scanf("%s", records[i].name);
		printf("input the score:\n");
		for (int j = 0; j < 3; j++) {
			scanf("%d", &records[i].score[j]);
		}
	}
	printf("\n");
	print(records, 5);
}

//t3用
static void print(Record* p,int n) {
	for (int i = 0; i < n; i++, p++) {
		Record record = *p;
		const char *format = "The student number is %d name is %s score is %d %d %d\n";
		printf(format, record.num, record.name, record.score[0], record.score[1], record.score[2]);
	}
}

static void t4() {
	Record records[5];
	Record *p = records;
	input(p ,5);
	print(p ,5);
}

//t4用
static void input(Record *p,int n) {
	for (int i = 0; i < n; i++,p++) {
		printf("input the num:\n");
		scanf("%d", &p->num);
		printf("input the name:\n");
		scanf("%s", p->name);
		printf("input the score:\n");
		for (int j = 0; j < 3; j++) {
			scanf("%d", &p->score[j]);
		}
	}
}

static void t5() {
	Record records[3];
	Record *p = records;
	input(p, 3);
	int sum = 0;
	double max = 0.0;
	int maxIndex = 0;
	for (int i = 0; i < 3; i++, p++) {
		double aver=0.0;
		Record record = *p;
		for (int j = 0; j < 3; j++) {
			aver += p->score[j];
			sum += p->score[j];
		}
		aver /= 3.0;
		if (aver > max) {
			max = aver;
			maxIndex = i;
		}
	}
	printf("3门课程的总平均成绩是%lf\n", sum / 9.0);
	p = records + maxIndex;
	printf("最高分学生的数据是 学号 %d 姓名 %s 3门课程成绩 %d %d %d 平均成绩 %lf\n", p->num, p->name, p->score[0], p->score[1], p->score[2], max);
}

static void t6() {
	Person *head = createPeople(13);
    exit(head,13);
	while (!head->live) 
		  head = head->next;
	printf("幸存者编号是 %d\n", head->num);
}

//t6用
static Person* createPeople(int n) {
	int num = 1;
	Person *head,*Tail,*p1, *p2;
	head = NULL;
	Tail = NULL;
	p1 = p2 =(Person *)malloc(personSize);
	while (num <=n) {
		if (num == 1) {
			p1->num = 1;
			p1->live = 1;
			head = p1;
			num++;
		}
		else {
			p1 = (Person *)malloc(personSize);
			p2->next = p1;
			p2 = p1;
			p1->num = num;
			p1->live = 1;
			num++;
		}
	}
	p2->next = Tail;
	return head;
}

//t6用
static void printPeople(Person *head) {
	Person *p = head;
	while (p != NULL) {
		printf("num: %d live: %d\n", p->num, p->live);
		p = p->next;
	}
}

//t6用
static  void exit(Person *p,int sum) {
	int count = 0;
	Person *head = p;
	while (sum>1)
	{
		    //圈内
			if (p->live) {
				count++;
				if (count % 3==0) {
					p->live = 0;
					sum--;
				}
				if (p->next==NULL) {
					p = head;
				}
				else
					p = p->next;
			}

			//圈外
			else {
				if (p->next == NULL) {
					p = head;
				}
				else
					p = p->next;
			}
	}


}

static void t7() {
	Student *head=createStudent();
	printStudent(head);
	printf("\n");

	/*printf("删除学号为22的学生:\n");
	head = del(head, 22);
	printStudent(head);
	printf("\n");*/

	printf("在学号为21的学生后添加学生:\n");
	head = insert(head,-1);
	printStudent(head);
	printf("\n");
}

//t7、t8、t9用
static Student* createStudent() {
	int num = 0;
	Student *head, *Tail, *p1, *p2;
	head = NULL;
	Tail = NULL;
	p1 = p2 = (Student *)malloc(studentSize);
	inputStudent(p1);
	while (p1->num != 0) {
		num++;
		if (num == 1) 
			head = p1;
		else 
			p2->next = p1;

		p2 = p1;
		p1 = (Student *)malloc(studentSize);
		inputStudent(p1);
	}
	p2->next = NULL;
	return head;
}

static void inputStudent(Student *stu) {
	printf("Input num:\n");
	scanf("%d", &stu->num);
	printf("Input name:\n");
	scanf("%s", stu->name);
	printf("Input age:\n");
	scanf("%d", &stu->age);
	//吃掉回车符
	getchar();
	printf("Input gender:\n");
	scanf("%c", &stu->gender);
	printf("Input score:\n");
	scanf("%f", &stu->score);
	
}

static void printStudent(Student *stu) {
	const char *format = "The Student num is %d name is %s age is %d gender is %c score is %4.2f\n";
	while (stu != NULL)
	{
		printf(format, stu->num, stu->name, stu->age, stu->gender, stu->score);
		stu = stu->next;
	}
}

//t7 t9 t11用
static Student* del(Student *head,int num) {
	Student *p = head;
	//删除头结点
	if (head->num == num) {
		if (head->next == NULL) {
			head = NULL;
		}
		else
		{
			Student *temp = head;
			head = head->next ;
			temp=NULL; 
			
		} 
	}

	else {


		Student* pre = p;
		while (p!= NULL) {
			if (p->num == num) {
				if (p->next == NULL) {
					pre->next = NULL;
					return head;
				}
				else {
					pre->next = p->next;
					return head;
				}
			}
			pre = p;
			p = p->next;
		}
	}
	return head;
}

//Todo 首项与末项
//num为-1表示插入头结点之前 num为999表示插入末尾
static Student *insert(Student *head, int num) {
	Student *p = head;
	Student *add = (Student *)malloc(studentSize);
	inputStudent(add);
	//直接插入头部
	if (num == -1) {
		add->next = head;
		head = add;
	}
	else {
		//直接插入尾部
		if (num == 999) {
			while (p->next != NULL) {
				p = p->next;
			}
		}
		else {
			while (p->num != num) {
				p = p->next;
			}
		}
		add->next = p->next;
		p->next = add;
	}
	return head;
}

static void t10() {
	
	Student *head = NULL;
	printf("请输入a链表:\n");
	Student *a = createStudent();
	printf("a链表数据如下:\n");
	printStudent(a);
	printf("\n");

	printf("请输入b链表:\n");
	Student *b = createStudent();
	printf("b链表数据如下:\n");
	printStudent(b);
	printf("\n");

	printf("合并后:\n");
	head = mergeStudents(a, b);
	printStudent(head);


	printf("\n");
}

static Student* mergeStudents(Student *p1,Student *p2) {
	Student *head = NULL;
	Student *af_p1 = p1;
	Student *af_p2 = p2;
	//a在插入后由于去掉了next(插入中破坏原链表结构) 不能直接循环遍历
	while (p1 != NULL) {
		af_p1 = p1->next;
		head = insertByScore(head, p1);
		p1 = af_p1;
	}

	while (p2 != NULL) {
		af_p2 = p2->next;
		head = insertByScore(head, p2);
		p2 = af_p2;
	}

	return head;
}

//head必须为有尾结点的完整链表
static Student *insertByScore(Student *head, Student *add) {
	Student *p = head;
	Student *prev = head;
	float score = add->score;
	//破坏原链接结构 不然新链表会在add后链接原add的链表,破坏新链表的后续结构
	add->next = NULL;

	//新链表为空链表
	if (p==NULL) {
		return add;
	}
	else {
		//第一个元素就大于add Bug:循环后操作构成循环链表
		if (p->score > score) {
			add->next = head;
			head = add;
			return head;
		}
		else {
			while (p->score < score) {
				//末尾
				if (p->next == NULL) {
					p->next = add;
					//add->next = NULL;
					return head;
				}
				else {
					prev = p;
					p = p->next;
				}
			}
			prev->next = add;
			add->next = p;
			return head;
		}
		
	}

}

static void t11() {
	Student *head = NULL;
	printf("请输入a链表:\n");
	Student *a = createStudent();
	printf("\n");
	printf("请输入b链表:\n");
	Student *b = createStudent();
	printf("\n");
	printf("a链表数据如下:\n");
	printStudent(a);
	printf("\n");
	printf("b链表数据如下:\n");
	printStudent(b);
	printf("\n");

	head=delStudents(a, b);
	printf("删除后数据如下:\n");
	printStudent(head);
	printf("\n");

}

//t11用
static Student* delStudents(Student *a,Student *b) {
	Student *head = a;
	//超过10个元素则动态扩大
	int buf = 10;
	int sum = 0;
	int *nums = (int*)malloc(buf * sizeof(int));
	int *large;
	while (b != NULL) {
		sum++;
		if (sum > buf) {
			//不赋值给指针nums的话 原有的指针nums会被释放掉
			nums = (int *)realloc(nums, (sum + 10) * sizeof(int));
			buf += 10;
		}
		    *(nums + sum - 1) = b->num;
			b = b->next;
	}

	int booldel = 0;
	int delnum = 0;
	while (a != NULL) {
		 booldel = 0;
		 delnum = 0;
		for (int i = 0; i < sum; i++) {
			if (a->num == *(nums + i)) {
				booldel = 1;
				delnum = a->num;
				break;
			}
		}
		if (booldel) {
			head=del(head, delnum);
		}

		a = a->next;
	}


	free(nums);
	nums = NULL;
	return head;
}

static void t12() {
	printf("请输入学生数据:\n");
	Student *head = createStudent();
	printf("学生数据如下:\n");
	printStudent(head);
	printf("\n");
	int age;
	printf("请输入学生年龄:\n");
	scanf("%d", &age);
	head = del2(head, age);
	printf("删除后学生数据如下:\n");
	printStudent(head);
}

//t12用
static Student* del2(Student *head, int age) {
	Student *p = head;
	//删除头结点
	if (head->age == age) {
		if (head->next == NULL) {
			head = NULL;
		}
		else
		{
			Student *temp = head;
			head = head->next;
			temp = NULL;

		}
	}

	else {

		Student* pre = p;
		while (p != NULL) {
			if (p->age == age) {
				if (p->next == NULL) {
					pre->next = NULL;
					return head;
				}
				else {
					pre->next = p->next;
					return head;
				}
			}
			pre = p;
			p = p->next;
		}
	}
	return head;
}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值