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;
}