C程序设计(第5版)谭浩强习题解答
第9章 用户自己建立数据类型
1.定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。
//9.1.1
#include
struct
{
int year;
int month;
int day;
}date;
int main()
{
int days;
printf("input year,month,day:");
scanf("%d,%d,%d", &date.year, &date.month, &date.day);
switch (date.month)
{
case 1: days = date.day; break;
case 2: days = date.day + 31; break;
case 3: days = date.day + 59; break;
case 4: days = date.day + 90; break;
case 5: days = date.day + 120; break;
case 6: days = date.day + 151; break;
case 7: days = date.day + 181; break;
case 8: days = date.day + 212; break;
case 9: days = date.day + 243; break;
case 10: days = date.day + 273; break;
case 11: days = date.day + 304; break;
case 12: days = date.day + 334; break;
}
if ((date.year % 4 == 0 && date.year % 100 != 0
|| date.year % 400 == 0) && date.month >= 3) days += 1;
printf("%d/%d is the %dth day in %d.\n", date.month, date.day, days, date.year);
return 0;
}
//9.1.2
#include
struct
{
int year;
int month;
int day;
}date;
int main()
{
int i, days;
int day_tab[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
printf("input year,month,day:");
scanf("%d,%d,%d", &date.year, &date.month, &date.day);
days = 0;
for (i = 1; i < date.month; i++)
days = days + day_tab[i];
days = days + date.day;
if ((date.year % 4 == 0 && date.year % 100 != 0 || date.year % 400 == 0) && date.month >= 3)
days = days + 1;
printf("%d/%d is the %dth day in %d.\n", date.month, date.day, days, date.year);
return 0;
}
2.写一个函数days,实现第1 题的计算。由主函数将年、月、日传递给days函数,计算后将日子数传回主函数输出。
//9.2.1
#include
struct y_m_d
{
int year;
int month;
int day;
}date;
int main()
{
int days(struct y_m_d date1);
printf("input year,month,day:");
scanf("%d,%d,%d", &date.year, &date.month, &date.day);
printf("%d/%d is the %dth day in %d.\n", date.month, date.day, days(date), date.year);
}
int days(struct y_m_d date1)
{
int sum;
switch (date1.month)
{
case 1: sum = date1.day; break;
case 2: sum = date1.day + 31; break;
case 3: sum = date1.day + 59; break;
case 4: sum = date1.day + 90; break;
case 5: sum = date1.day + 120; break;
case 6: sum = date1.day + 151; break;
case 7: sum = date1.day + 181; break;
case 8: sum = date1.day + 212; break;
case 9: sum = date1.day + 243; break;
case 10: sum = date1.day + 273; break;
case 11: sum = date1.day + 304; break;
case 12: sum = date1.day + 334; break;
}
if ((date1.year % 4 == 0 && date1.year % 100 != 0 || date1.year % 400 == 0) && date1.month >= 3)
sum += 1;
return(sum);
}
//9.2.2
#include
struct y_m_d
{
int year;
int month;
int day;
} date;
int main()
{
int days(int year, int month, int day);
int days(int, int, int);
int day_sum;
printf("input year,month,day:");
scanf("%d,%d,%d", &date.year, &date.month, &date.day);
day_sum = days(date.year, date.month, date.day);
printf("%d / %d is the %dth day in %d.\n", date.month, date.day, day_sum, date.year);
}
int days(int year, int month, int day)
{
int day_sum, i;
int day_tab[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
day_sum = 0;
for (i = 1; i < month; i++)
day_sum += day_tab[i];
day_sum += day;
if ((year % 4 == 0 && year % 100 != 0 || year % 4 == 0) && month >= 3)
day_sum += 1;
return(day_sum);
}
3.编写一个函数print,打印一个学生的成绩数组,该数组中有5个学生的数据记录,每个记录包括num,name,score[3],用主函数输人这些记录,用print函数输出这些记录。
#include
#define N 5
struct student
{
char num[6];
char name[8];
int score[4];
}stu[N];
int main()
{
void print(struct student stu[6]);
int i, j;
for (i = 0; i < N; i++)
{
printf("\ninput score of student %d:\n", i + 1);
printf("NO.: ");
scanf("%s", stu[i].num);
printf("name: ");
scanf("%s", stu[i].name);
for (j = 0; j < 3; j++)
{
printf("score %d:", j + 1);
scanf("%d", &stu[i].score[j]);
}
printf("\n");
}
print(stu);
return 0;
}
void print(struct student stu[6])
{
int i, j;
printf("\n NO. name score1 score2 score3\n");
for (i = 0; i < N; i++)
{
printf("%5s%10s", stu[i].num, stu[i].name);
for (j = 0; j < 3; j++)
printf("%9d", stu[i].score[j]);
printf("\n");
}
}
4.在第3题的基础上,编写一个函数input,用来输人5个学生的数据记录。
#include
#define N 5
struct student
{
char num[6];
char name[8];
int score[4];
} stu[N];
int main()
{
void input(struct student stu[]);
void print(struct student stu[]);
input(stu);
print(stu);
return 0;
}
void input(struct student stu[])
{
int i, j;
for (i = 0; i < N; i++)
{
printf("input scores of student %d:\n", i + 1);
printf("NO.: ");
scanf("%s", stu[i].num);
printf("name: ");
scanf("%s", stu[i].name);
for (j = 0; j < 3; j++)
{
printf("score %d:", j + 1);
scanf("%d", &stu[i].score[j]);
}
printf("\n");
}
}
void print(struct student stu[6])
{
int i, j;
printf("\n NO. name score1 score2 score3\n");
for (i = 0; i < N; i++)
{
printf("%5s%10s", stu[i].num, stu[i].name);
for (j = 0; j < 3; j++)
printf("%9d", stu[i].score[j]);
printf("\n");
}
}
5.有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩,从键盘输人10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。
#include
#define N 10
struct student
{
char num[6];
char name[8];
float score[3];
float avr;
} stu[N];
int main()
{
int i, j, maxi;
float sum, max, average;
for (i = 0; i < N; i++)
{
printf("input scores of student %d:\n", i + 1);
printf("NO.:");
scanf("%s", stu[i].num);
printf("name:");
scanf("%s", stu[i].name);
for (j = 0; j < 3; j++)
{
printf("score %d:", j + 1);
scanf("%f", &stu[i].score[j]);
}
}
average = 0;
max = 0;
maxi = 0;
for (i = 0; i < N; i++)
{
sum = 0;
for (j = 0; j < 3; j++)
sum += stu[i].score[j];
stu[i].avr = sum / 3.0;
average += stu[i].avr;
if (sum > max)
{
max = sum;
maxi = i;
}
}
average /= N;
printf(" NO. name score1 score2 score3 average\n");
for (i = 0; i < N; i++)
{
printf("%5s%10s", stu[i].num, stu[i].name);
for (j = 0; j < 3; j++)
printf("%9.2f", stu[i].score[j]);
printf(" %8.2f\n", stu[i].avr);
}
printf("average=%5.2f\n", average);
printf("The highest score is : student %s,%s\n", stu[maxi].num, stu[maxi].name);
printf("his scores are:%6.2f,%6.2f,%6.2f,average:%5.2f.\n",
stu[maxi].score[0], stu[maxi].score[1], stu[maxi].score[2], stu[maxi].avr);
return 0;
}
6.13个人围成一圈,从第1个人开始顺序报号1,2,3。凡报到3者退出圈子。找出最后留在圈子中的人原来的序号。要求用链表实现。
#include
#define N 13
struct person
{
int number;
int nextp;
} link[N + 1];
int main()
{
int i, count, h;
for (i = 1; i <= N; i++)
{
if (i == N)
link[i].nextp = 1;
else
link[i].nextp = i + 1;
link[i].number = i;
}
printf("\n");
count = 0;
h = N;
printf("sequence that persons leave the circle:\n");
while (count < N - 1)
{
i = 0;
while (i != 3)
{
h = link[h].nextp;
if (link[h].number)
i++;
}
printf("%4d", link[h].number);
link[h].number = 0;
count++;
}
printf("\nThe last one is ");
for (i = 1; i <= N; i++)
if (link[i].number)
printf("%3d", link[i].number);
printf("\n");
return 0;
}
7.在第9章例9.9和例9.10的基础上,写一个函数del,用来删除动态链表中指定的节点。
#include
struct student
{
long num;
float score;
struct student *next;
};
int n;
struct student *del(struct student *head, long num)
{
struct student *p1, *p2;
if (head == NULL) //是空表
{
printf("\nlist null!\n");
return(head);
}
p1 = head; //使p1指向第一个结点
while (num != p1->num && p1->next != NULL) //p1指向的不是所要找的结点且后面还有结点
{
p2 = p1; p1 = p1->next;
} //p1后移一个结点
if (num == p1->num) //找到了
{
if (p1 == head)head = p1->next; //若p1指向的是首结点,把第二个结点地址赋予head
else p2->next = p1->next; //否则将下一结点地址赋给前一结点地址
printf("delete:%ld\n", num);
n = n - 1;
}
else printf("%ld not been found!\n", num); //找不到该结点
return(head);
}
8.写一个函数insert,用来向一个动态链表插入结点。
#include
struct student
{
long num;
float score;
struct student*next;
};
int n;
struct student *insert(struct student *head, struct student *stud)
{
struct student *p0, *p1, *p2;
p1 = head; //使p1指向第一个结点
p0 = stud; //指向要插入的结点
if (head == NULL) //原来的链表是空表
{
head = p0; p0->next = NULL;
} //使p0指向的结点作为头结点
else
{
while ((p0->num > p1->num) && (p1->next != NULL))
{
p2 = p1; //使p2指向刚才p1指向的结点
p1 = p1->next;
} //p1后移一个结点
if (p0->num <= p1->num)
{
if (head == p1) head = p0; //插到原来第一个结点之前
else p2->next = p0; //插到p2指向的结点之后
p0->next = p1;
}
else
{
p1->next = p0;
p0->next = NULL; //插到最后的结点之后
}
}
n = n + 1; //结点数加1
return (head);
}
9.综合本章例9.9(建立链表的函数creat)、例9.10(输出链表的函数print)和本章习题第7题(删除链表中结点的函数del)、第8题(插入结点的函数insert),再编写一个主函数,先后调用这些函数。用以上5个函数组成一个程序,实现链表的建立、输出、删除和插入,在主函数中指定需要删除和插人的结点的数据。
//9.9.1
#include
#include
#define LEN sizeof(struct student)
struct student
{
long num;
float score;
struct student *next;
};
int n;
int main()
{
struct student *creat();
struct student *del(struct student *, long);
struct student *insert(struct student *, struct student *);
void print(struct student *);
struct student *head, stu;
long del_num;
printf("input records:\n");
head = creat();
print(head);
printf("input the deleted number:");
scanf("%ld", &del_num);
head = del(head, del_num);
print(head);
printf("input the inserted record:");
scanf("%ld,%f", &stu.num, &stu.score);
head = insert(head, &stu);
print(head);
return 0;
}
struct student *creat()
{
struct student *head;
struct student *p1, *p2;
n = 0;
p1 = p2 = (struct student*) malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
head = NULL;
while (p1->num != 0)
{
n = n + 1;
if (n == 1)head = p1;
else p2->next = p1;
p2 = p1;
p1 = (struct student*)malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
}
p2->next = NULL;
return(head);
}
struct student *del(struct student *head, long num)
{
struct student *p1, *p2;
if (head == NULL)
{
printf("\nlist null!\n");
return(head);
}
p1 = head;
while (num != p1->num && p1->next != NULL)
{
p2 = p1; p1 = p1->next;
}
if (num == p1->num)
{
if (p1 == head)head = p1->next;
else p2->next = p1->next;
printf("delete:%ld\n", num);
n = n - 1;
}
else printf("%ld not been found!\n", num);
return(head);
}
struct student *insert(struct student *head, struct student *stud)
{
struct student *p0, *p1, *p2;
p1 = head;
p0 = stud;
if (head == NULL)
{
head = p0; p0->next = NULL;
}
else
{
while ((p0->num > p1->num) && (p1->next != NULL))
{
p2 = p1;
p1 = p1->next;
}
if (p0->num <= p1->num)
{
if (head == p1) head = p0;
else p2->next = p0;
p0->next = p1;
}
else
{
p1->next = p0; p0->next = NULL;
}
}
n = n + 1;
return(head);
}
void print(struct student *head)
{
struct student *p;
printf("\nNow,These %d records are:\n", n);
p = head;
if (head != NULL)
do
{
printf("%ld %5.1f\n", p->num, p->score);
p = p->next;
} while (p != NULL);
}
//9.9.2
#include
#include
#define NULL 0
#define LEN sizeof(struct student)
struct student
{
long num;
float score; struct student *next;
};
int n;
int main()
{
struct student *creat();
struct student *del(struct student *, long);
struct student *insert(struct student *, struct student *);
void print(struct student *);
struct student *head, stu;
long del_num;
printf("input records:\n");
head = creat();
print(head);
printf("input the deleted number:");
scanf("%ld", &del_num);
head = del(head, del_num);
print(head);
printf("input the inserted record:");
scanf("%ld,%f", &stu.num, &stu.score);
head = insert(head, &stu);
print(head);
printf("input the inserted record:");
scanf("%ld,%f", &stu.num, &stu.score);
head = insert(head, &stu);
print(head);
return 0;
}
struct student *creat()
{
struct student *head;
struct student *p1, *p2;
n = 0;
p1 = p2 = (struct student*) malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
head = NULL;
while (p1->num != 0)
{
n = n + 1;
if (n == 1)head = p1;
else p2->next = p1;
p2 = p1;
p1 = (struct student*)malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
}
p2->next = NULL;
return(head);
}
struct student *del(struct student *head, long num)
{
struct student *p1, *p2;
if (head == NULL)
{
printf("\nlist null!\n");
return(head);
}
p1 = head;
while (num != p1->num && p1->next != NULL)
{
p2 = p1; p1 = p1->next;
}
if (num == p1->num)
{
if (p1 == head)head = p1->next;
else p2->next = p1->next;
printf("delete:%ld\n", num);
n = n - 1;
}
else printf("%ld not been found!\n", num);
return(head);
}
struct student *insert(struct student *head, struct student *stud)
{
struct student *p0, *p1, *p2;
p1 = head;
p0 = stud;
if (head == NULL)
{
head = p0; p0->next = NULL;
}
else
{
while ((p0->num > p1->num) && (p1->next != NULL))
{
p2 = p1;
p1 = p1->next;
}
if (p0->num <= p1->num)
{
if (head == p1) head = p0;
else p2->next = p0;
p0->next = p1;
}
else
{
p1->next = p0; p0->next = NULL;
}
}
n = n + 1;
return(head);
}
void print(struct student *head)
{
struct student *p;
printf("\nNow,These %d records are:\n", n);
p = head;
if (head != NULL)
do
{
printf("%ld %5.1f\n", p->num, p->score);
p = p->next;
} while (p != NULL);
}
//9.9.3
#include
#include
#define LEN sizeof(struct student)
struct student
{
long num;
float score;
struct student *next;
};
int n;
int main()
{
struct student *creat();
void print(struct student *);
struct student *del(struct student *, long);
struct student *insert(struct student *, struct student *);
struct student *head, *stu;
long del_num;
printf("input records:\n");
head = creat();
print(head);
printf("input the deleted number:");
scanf("%ld", &del_num);
while (del_num != 0)
{
head = del(head, del_num);
print(head);
printf("input the deleted number:");
scanf("%ld", &del_num);
}
printf("\ninput the inserted record:");
stu = (struct student *) malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
while (stu->num != 0)
{
head = insert(head, stu);
print(head);
printf("input the inserted record:");
stu = (struct student *)malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
}
return 0;
}
struct student *creat()
{
struct student *head;
struct student *p1, *p2;
n = 0;
p1 = p2 = (struct student*) malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
head = NULL;
while (p1->num != 0)
{
n = n + 1;
if (n == 1)head = p1;
else p2->next = p1;
p2 = p1;
p1 = (struct student*)malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
}
p2->next = NULL;
return(head);
}
struct student *del(struct student *head, long num)
{
struct student *p1, *p2;
if (head == NULL)
{
printf("\nlist null!\n"); return(head);
}
p1 = head;
while (num != p1->num && p1->next != NULL)
{
p2 = p1; p1 = p1->next;
}
if (num == p1->num)
{
if (p1 == head)head = p1->next;
else p2->next = p1->next;
printf("delete:%ld\n", num);
n = n - 1;
}
else printf("%ld not been found!\n", num);
return(head);
}
struct student *insert(struct student *head, struct student *stud)
{
struct student *p0, *p1, *p2;
p1 = head;
p0 = stud;
if (head == NULL)
{
head = p0; p0->next = NULL;
}
else
{
while ((p0->num > p1->num) && (p1->next != NULL))
{
p2 = p1;
p1 = p1->next;
}
if (p0->num <= p1->num)
{
if (head == p1) head = p0;
else p2->next = p0;
p0->next = p1;
}
else
{
p1->next = p0; p0->next = NULL;
}
}
n = n + 1;
return(head);
}
void print(struct student *head)
{
struct student *p;
printf("\nNow,These %d records are:\n", n);
p = head;
if (head != NULL)
do
{
printf("%ld %5.1f\n", p->num, p->score);
p = p->next;
} while (p != NULL);
}
10.已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并, 按学号升序排列。
#include
#include
#define LEN sizeof(struct student)
struct student
{
long num;
int score;
struct student *next;
};
struct student lista, listb;
int n, sum = 0;
int main()
{
struct student *creat(void);
struct student *insert(struct student *, struct student *);
void print(struct student *);
struct student *ahead, *bhead, *abh;
printf("input list a:\n");
ahead = creat();
sum = sum + n;
printf("input list b:\n");
bhead = creat();
sum = sum + n;
abh = insert(ahead, bhead);
print(abh);
return 0;
}
struct student *creat(void) //建立链表函数
{
struct student *p1, *p2, *head;
n = 0;
p1 = p2 = (struct student *)malloc(LEN);
printf("input number & scores of student:\n");
printf("if number is 0,stop inputing.\n");
scanf("%ld,%d", &p1->num, &p1->score);
head = NULL;
while (p1->num != 0)
{
n = n + 1;
if (n == 1)
head = p1;
else
p2->next = p1;
p2 = p1;
p1 = (struct student *)malloc(LEN);
scanf("%ld,%d", &p1->num, &p1->score);
}
p2->next = NULL;
return(head);
}
struct student *insert(struct student *ah, struct student *bh) //插入函数
{
struct student * pa1, *pa2, *pb1, *pb2;
pa2 = pa1 = ah;
pb2 = pb1 = bh;
do
{
while ((pb1->num > pa1->num) && (pa1->next != NULL))
{
pa2 = pa1;
pa1 = pa1->next;
}
if (pb1->num <= pa1->num)
{
if (ah == pa1)
ah = pb1;
else
pa2->next = pb1;
pb1 = pb1->next;
pb2->next = pa1;
pa2 = pb2;
pb2 = pb1;
}
} while ((pa1->next != NULL) || (pa1 == NULL && pb1 != NULL));
if ((pb1 != NULL) && (pb1->num > pa1->num) && (pa1->next == NULL))
pa1->next = pb1;
return(ah);
}
void print(struct student *head) //输出函数
{
struct student *p;
printf("There are %d records: \n", sum);
p = head;
if (p != NULL)
do
{
printf("%ld %d\n", p->num, p->score);
p = p->next;
} while (p != NULL);
}
11.有两个链表a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。
#include
#include
#define LA 4
#define LB 5
struct student
{
int num;
char name[8];
struct student *next;
} a[LA], b[LB];
int main()
{
struct student a[LA] = { {101,"Wang"},{102,"Li"},{105,"Zhang"},{106,"Wei"} };
struct student b[LB] = { {103,"Zhang"},{104,"Ma"},{105,"Chen"},{107,"Guo"},{108,"lui"} };
int i;
struct student *p, *p1, *p2, *head1, *head2;
head1 = a;
head2 = b;
printf(" list A: \n");
for (p1 = head1, i = 1; i <= LA; i++)
{
if (i < LA) p1->next = a + i;
else p1->next = NULL;
printf("%4d%8s\n", p1->num, p1->name);
if (i < LA) p1 = p1->next;
}
printf("\n list B:\n");
for (p2 = head2, i = 1; i <= LB; i++)
{
if (i < LB) p2->next = b + i;
else p2->next = NULL;
printf("%4d%8s\n", p2->num, p2->name);
if (i < LB) p2 = p2->next;
}
p1 = head1;
while (p1 != NULL)
{
p2 = head2;
while ((p1->num != p2->num) && (p2->next != NULL))
p2 = p2->next;
if (p1->num == p2->num)
{
if (p1 == head1)
head1 = p1->next;
else
{
p->next = p1->next; p1 = p1->next;
}
}
else
{
p = p1; p1 = p1->next;
}
}
printf("\nresult:\n");
p1 = head1;
while (p1 != NULL)
{
printf("%4d %7s \n", p1->num, p1->name);
p1 = p1->next;
}
return 0;
}
12.建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。
#include
#include
#define LEN sizeof(struct student)
struct student
{
char num[6];
char name[8];
char sex[2];
int age;
struct student *next;
} stu[10];
int main()
{
struct student *p, *pt, *head;
int i, length, iage, flag = 1;
int find = 0; //找到待删除元素 find=1,否则find=0
while (flag == 1)
{
printf("input length of list(<10):");
scanf("%d", &length);
if (length < 10)
flag = 0;
}
//建立链表
for (i = 0; i < length; i++)
{
p = (struct student *) malloc(LEN);
if (i == 0)
head = pt = p;
else
pt->next = p;
pt = p;
printf("NO.:");
scanf("%s", p->num);
printf("name:");
scanf("%s", p->name);
printf("sex:");
scanf("%s", p->sex);
printf("age:");
scanf("%d", &p->age);
}
p->next = NULL;
p = head;
printf("\n NO. name sex age\n"); //显示
while (p != NULL)
{
printf("%4s%8s%6s%6d\n", p->num, p->name, p->sex, p->age);
p = p->next;
}
//删除
printf("input age:"); //输入待删年龄
scanf("%d", &iage);
pt = head;
p = pt;
if (pt->age == iage) //链头是待删元素
{
p = pt->next;
head = pt = p;
find = 1;
}
else //链头不是待删元素
pt = pt->next;
while (pt != NULL)
{
if (pt->age == iage)
{
p->next = pt->next;
find = 1;
}
else //中间结点不是待删元素
p = pt;
pt = pt->next;
}
if (!find)
printf(" not found %d.", iage);
p = head;
printf("\n NO. name sex age\n"); //显示结果
while (p != NULL)
{
printf("%4s%8s", p->num, p->name);
printf("%6s%6d\n", p->sex, p->age);
p = p->next;
}
return 0;
}