本文主要是介绍C Primer Plus第十四章编程练习,仅供参考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
第十四章编程练习
第一个问题让我们改写复习题5,创建一个函数去计算一年到某个月份的天数,在一个结构数组中去存储相关数据。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
struct month
{char name[20];char abbr[4];int days;int number;
};
const struct month months[12] = { {"January", "Jan", 31, 1}, {"February", "Feb", 28, 2}, {"March", "Mar", 31, 3}, {"April", "Apr", 30, 4}, {"May", "May", 31, 5}, {"June", "Jun", 30, 6}, {"July", "Jul", 31, 7}, {"August", "Aug", 31, 8}, {"September", "Sep", 30, 9}, {"October", "Oct", 31, 10}, {"November", "Nov", 30, 11}, {"December", "Dec", 31, 12}
};
int jiSuan(const char *);
int main(void){char input[20];int total;printf("请输入一个月份:\n");while (scanf("%s",input) == 1 && input[0] != 'q'){total = jiSuan(input);if (total>0){printf("到%s月为止,一共有%d天。\n",input,total);}else{printf("输入的月份可能存在错误,请检查。\n");}printf("请输入下一个月份。输入q结束循环\n"); }printf("Done!!!");return 0;
}
int jiSuan(const char * in){int n = 0;int r = 0;for (int i = 0; i < 12; i++){if(strcmp(in,months[i].name) == 0){n = months[i].number;}}for (int i = 0; i < n; i++){r += months[i].days;}return r;
}
接下来,我们来看一下第二题的要求,获取输入的日、月和年,月份可以是三种格式,然后返回一年中到指定日子的总天数。这里就有一个问题了,输入了年份,那么平闰年要处理吗,题目里并没有明确的说明。我们简单的对其处理一下,完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
struct month
{char name[20];char abbr[4];int days;char number[3];
};
const struct month months[12] = { {"January", "Jan", 31, "1"}, {"February", "Feb", 28, "2"}, {"March", "Mar", 31, "3"}, {"April", "Apr", 30, "4"}, {"May", "May", 31, "5"}, {"June", "Jun", 30, "6"}, {"July", "Jul", 31, "7"}, {"August", "Aug", 31, "8"}, {"September", "Sep", 30, "9"}, {"October", "Oct", 31, "10"}, {"November", "Nov", 30, "11"}, {"December", "Dec", 31, "12"}
};
int jiSuan(const char *, int, int);
int main(void){char input[20];int ri,year;int total;int flag;printf("请输入一个月份:\n");while (scanf("%s",input) == 1 && input[0] != 'q'){printf("请输入截止到这个月的几号:\n");flag = 0;scanf("%d",&ri);printf("请输入年份:\n");scanf("%d",&year);if ((year % 4 == 0 && year % 100 != 0)||year % 400 == 0){flag = 1;}total = jiSuan(input,ri,flag);if (total>0){printf("到%s月为止,一共有%d天。\n",input,total);}else{printf("输入的月份可能存在错误,请检查。\n");}printf("请输入下一个月份。输入q结束循环\n"); }printf("Done!!!");return 0;
}
int jiSuan(const char * in, int ri, int flag){int n = 0;int r = ri;for (int i = 0; i < 12; i++){if(strcmp(in,months[i].name) == 0 ||strcmp(in,months[i].abbr) == 0||strcmp(in,months[i].number) == 0){n = atoi(months[i].number);}}for (int i = 0; i < n-1; i++){r += months[i].days;}if (flag == 1 && n > 2){r += 1;}return r;
}
下面,我们来看一下第三题的要求,让我们修改程序清单14.2,然后按照几种顺序去输出图书信息。完整程序代码以及运行结果如下:
/* manybook.c -- 包含多本书的图书目录 */
#include <stdio.h>
#include <string.h>
char * s_gets(char * st, int n);
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 100 /* 书籍的最大数量 */struct book { /* 建立 book 模板 */char title[MAXTITL];char author[MAXAUTL];float value;
};
void ziMu(struct book library[MAXBKS],int count);
void jgMu(struct book library[MAXBKS],int count);
int main(void)
{struct book library[MAXBKS]; /* book 类型结构的数组 */int count = 0;int index;printf("Please enter the book title.\n");printf("Press [enter] at the start of a line to stop.\n");while (count < MAXBKS && s_gets(library[count].title, MAXTITL) != NULL&& library[count].title[0] != '\0'){printf("Now enter the author.\n");s_gets(library[count].author, MAXAUTL);printf("Now enter the value.\n");scanf("%f", &library[count++].value);while (getchar() != '\n')continue; /* 清理输入行*/if (count < MAXBKS)printf("Enter the next title.\n");}if (count > 0){printf("Here is the list of your books:\n");for (index = 0; index < count; index++)printf("%s by %s: $%.2f\n", library[index].title,library[index].author, library[index].value);ziMu(library,count);jgMu(library,count);}elseprintf("No books? Too bad.\n");return 0;
}char * s_gets(char * st, int n)
{char * ret_val;char * find;ret_val = fgets(st, n, stdin);if (ret_val){find = strchr(st, '\n'); // 查找换行符if (find) // 如果地址不是 NULL,*find = '\0'; // 在此处放置一个空字符elsewhile (getchar() != '\n')continue; // 处理输入行中剩余的字符}return ret_val;
}
void ziMu(struct book library[MAXBKS],int count){struct book libraryz[MAXBKS]; struct book lz;for (int i = 0; i < count; i++){libraryz[i] = library[i];}for (int i = 0; i < count; i++){for (int j = i+1; j < count; j++){if (strcmp(libraryz[i].title,libraryz[j].title)>0){lz = libraryz[i];libraryz[i] = libraryz[j];libraryz[j] = lz;} }}printf("Here is the list of your books(按照字母顺序):\n");for (int index = 0; index < count; index++)printf("%s by %s: $%.2f\n", libraryz[index].title,libraryz[index].author, libraryz[index].value);
}
void jgMu(struct book library[MAXBKS],int count){struct book libraryj[MAXBKS]; struct book lz;for (int i = 0; i < count; i++){libraryj[i] = library[i];}for (int i = 0; i < count; i++){for (int j = i+1; j < count; j++){if (libraryj[i].value > libraryj[j].value){lz = libraryj[i];libraryj[i] = libraryj[j];libraryj[j] = lz;} }}printf("Here is the list of your books(按照图书价格):\n");for (int index = 0; index < count; index++)printf("%s by %s: $%.2f\n", libraryj[index].title,libraryj[index].author, libraryj[index].value);
}
接着,来看一下第四题的内容,分析一下要求
创建一个含有两个成员的结构模版,其中一个成员是一个有三个成员的结构,初始化一个数组,内含五组数据,然后按照格式打印数据。说实话,这老外的名字格式我属实看的有点懵。那个是名字,那个又是姓,啥又是中间名啊。算了,按照自己的理解来吧。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define SIZE 44
struct name{char ming[SIZE];char zhong[SIZE];char xing[SIZE];
};
struct test
{char shebao[100];struct name hpe;
};
struct test arr[5] ={{"302039823",{"Dribble","M","Flossie"}},{"231907821",{"Rell","C","Black"}},{"124324221",{"Dick","","James"}},{"124454545",{"Rose","","Kell"}},{"456565451",{"Pell","II","Gala"}}
};
void daYin(const struct test (*ptr));
void daYint(struct test ac[5]);
int main(void){struct test (*ptr) = arr;printf("----------程序开始----------\n");daYin(ptr);printf("----------------------------\n");daYint(arr);printf("----------程序结束----------\n");return 0;
}
void daYin(const struct test (*ptr)){for (int i = 0; i < 5; i++){if (strlen((ptr+i)->hpe.zhong) > 0){printf("%s, %s %s. -- %s\n",(ptr+i)->hpe.ming,(ptr+i)->hpe.xing,(ptr+i)->hpe.zhong,(ptr+i)->shebao);}else{printf("%s, %s -- %s\n",(ptr+i)->hpe.ming,(ptr+i)->hpe.xing,(ptr+i)->shebao);}}
}
void daYint(struct test ac[5]){for (int i = 0; i < 5; i++){if (strlen(ac[i].hpe.zhong) > 0){printf("%s, %s %s. -- %s\n",ac[i].hpe.ming,ac[i].hpe.xing,ac[i].hpe.zhong,ac[i].shebao);}else{printf("%s, %s -- %s\n",ac[i].hpe.ming,ac[i].hpe.xing,ac[i].shebao);}}
}
下面,我们来分析一下下一个问题的要求,主要是要去计算学生的平均成绩,用一个嵌套结构去记录数值。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define SIZE 44
#define CSIZE 4
struct name
{char ming[SIZE];char xing[SIZE];
};
struct student
{struct name stu;float grade[3];float average;
};
int main(void){struct student students[CSIZE] = {{{"Rose","Hadden"}},{{"Hadvi","Dick"}},{{"James","Kell"}},{{"Yang","Auto"}}};for (int i = 0; i < CSIZE; i++){int sum = 0, count = 0;printf("请输入 %s %s 同学的成绩:\n",students[i].stu.ming,students[i].stu.xing);for (int j = 0; j < 3; j++){if (scanf("%f",&students[i].grade[j]) != 0){sum += students[i].grade[j];count++;}} students[i].average = sum/count; }printf("名字 姓氏 成绩1 成绩2 成绩3 平均成绩\n");for (int i = 0; i < CSIZE; i++){printf("%s %s %.2f %.2f %.2f %.2f\n",students[i].stu.ming,students[i].stu.xing,students[i].grade[0],students[i].grade[1],students[i].grade[2],students[i].average);}int sumb = 0;for (int i = 0; i < CSIZE; i++){sumb += students[i].average;}float ave = sumb / CSIZE;printf("班级的平均成绩为:%.2f\n",ave);return 0;
}
好的,接下来,来看一下第六题的要求是什么,处理一个垒球队的球员上场数据,计算后续的数据,比如安打率之类的高级数据。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define SIZE 44
#define TXT "D:\\C\\test14.txt"
struct player
{int number;char ming[SIZE];char xing[SIZE];int shang;int ji;int zou;int rbi;float adl;
};
struct player players[19] = {{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0}
};
int main(void){FILE * in;int count;int n, s, j, z, r;float a;char m[SIZE], x[SIZE];if((in = fopen(TXT,"r")) == NULL){fprintf(stderr,"无法打开文件%s",TXT);exit(EXIT_FAILURE);}rewind(in);while (feof(in) != 1 &&(count = fscanf(in,"%d %s %s %d %d %d %d",&n,m,x,&s,&j,&z,&r)) && count == 7){players[n].number = n;strcpy(players[n].ming,m);strcpy(players[n].xing,x);players[n].shang += s;players[n].ji += j;players[n].zou += z;players[n].rbi += r; }printf("号码 名字 姓氏 上场数 击中数 走垒数 RBI 安打率\n");for (int i = 0; i < 19; i++){if (players[i].shang > 0){a = (float)players[i].ji/(float)players[i].shang;}else{a = 0;}players[i].adl = a;printf("%-5d %-6s %-6s %5d %7d %9d %6d %7.2f\n",players[i].number,players[i].ming,players[i].xing,players[i].shang,players[i].ji,players[i].zou,players[i].rbi,a);}return 0;
}
接着,我们来看一下第七题的要求以及具体实现思路,要求我们去修改程序清单14.14,然后增加一个修改以及删除文件中的图书信息,这一个确实比较复杂,用了很长时间,也没有做出最终的效果,只是粗略的实现了一下这部分的功能,其实还有很大的优化空间。我们来看一下程序的完整代码以及运行结果:
/* booksave.c -- 在文件中保存结构中的内容 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 10 /* 最大书籍数量 */
char * s_gets(char * st, int n);
struct book { /* 建立 book 模板 */char title[MAXTITL];char author[MAXAUTL];float value;int delete;
};
void update(struct book * lbi,int n);
int main(void)
{struct book library[MAXBKS]; /* 结构数组 */int count = 0;int index, filecount;FILE * pbooks;int size = sizeof(struct book);char yn,ud;int delcount = 0;if ((pbooks = fopen("book.dat", "r+b")) == NULL){fputs("Can't open book.dat file\n", stderr);exit(1);}rewind(pbooks); /* 定位到文件开始 */while (count < MAXBKS && fread(&library[count], size,1, pbooks) == 1){if (count == 0)puts("Current contents of book.dat:");if (library[count].delete == 0){printf("%s by %s: $%.2f\n", library[count].title,library[count].author, library[count].value);printf("是否要对该条内容执行修改或删除操作(y/n):\n");scanf("%c",&yn);while (getchar() != '\n'){continue;}if (yn == 'y'){printf("如要执行修改操作请输入u,删除操作请输入d。\n");scanf("%c",&ud);while (getchar() != '\n'){continue;}if (ud == 'u'){printf("开始修改\n");update(library,count);printf("已修改\n");}else if (ud == 'd'){printf("已删除\n");library[count].delete = 1;delcount++;}}count++;}}filecount = count - delcount;if (filecount == MAXBKS){fputs("The book.dat file is full.", stderr);exit(2);}int newcount = 0, newH =0;if (delcount > 0){while (library[newcount].delete == 0){newcount++;}count = newcount;}puts("Please add new book titles.");puts("Press [enter] at the start of a line to stop.");while (filecount < MAXBKS && s_gets(library[count].title, MAXTITL) != NULL&& library[count].title[0] != '\0'){puts("Now enter the author.");s_gets(library[count].author, MAXAUTL);puts("Now enter the value.");scanf("%f", &library[count].value);library[count].delete = 0;while (getchar() != '\n')continue; /* 清理输入行 */if (count < MAXBKS)puts("Enter the next title.");newH++;if (delcount > 0){while (library[newcount].delete == 0){newcount++;}count = newcount;}else{count++;} }int nownumber = filecount + newH;if (nownumber > 0){rewind(pbooks);puts("Here is the list of your books:");for (index = 0; index < nownumber; index++){printf("%s by %s: $%.2f\n", library[index].title,library[index].author, library[index].value);fwrite(&library[index], size, 1, pbooks);}}elseputs("No books? Too bad.\n");puts("Bye.\n");fclose(pbooks);return 0;
}char * s_gets(char * st, int n)
{char * ret_val;char * find;ret_val = fgets(st, n, stdin);if (ret_val){find = strchr(st, '\n'); // 查找换行符if (find) // 如果地址不是 NULL,*find = '\0'; // 在此处放置一个空字符elsewhile (getchar() != '\n')continue; // 清理输入行}return ret_val;
}
void update(struct book * lbi,int n){struct book the;printf("暂不支持修改单个数据,请重新输入该条图书数据。\n");puts("请输入要修改的图书名。");s_gets(the.title,MAXTITL);puts("请输入图书作者。");s_gets(the.author, MAXAUTL);puts("请输入图书价格。");scanf("%f", &the.value);the.delete = 0;while (getchar() != '\n')continue; *(lbi + n) = the;
}
首先是,从零添加图书,结果如下
然后再次运行程序,回显这些文件,并测试修改以及删除操作
观察得知,修改操作已经没有问题,但是还可以优化,比如单独修改其中的某个值,这里就先不讨论了,我们再去改一下删除的问题。又仔细看了一下,发现好像是在选择操作的时候输错了值,跳过了一步,导致删除没有成功,我们再单独测试一遍删除操作。
由此可见,没有问题,再测试一下只删除,不添加的操作。
好,综上,这一个问题就简单的实现了基本的要求,当然如果时间充裕的话,还可以像我说的一样,进行用户使用体验的优化,比如可以选择修改某个值,其实实现起来也不是很难,毕竟你全部更新都实现了,更新单个值的内容的话,只是还要加一步选择操作。自己思考这来实现吧。下面,我们来看一下第八题的要求。
巨人航空公司,哈哈,讲道理不怕艾伦塔塔开你吗?开玩笑哈,我们接着看要求。飞机上有十二个座位,每天飞行一个航班,给了我们结构的数据内容,实现菜单的内容,:选择方法,输入其字母标签,a:显示空座位数,b:显示空座位列表,c:显示按字母顺序排列的座位列表,d:为客户分配座位,e:删除座位分配,f:退出,选择d或者e提示用户进行额外输入,好,下面来看一下具体实现以及运行结果:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define SEATNUMBER 12
#define SIZE 44
struct seat
{char number[SIZE];int flag;//0表示没有被预定,1表示已经被预定char ming[SIZE];char xing[SIZE];
};
struct seat seats[SEATNUMBER] = {{"JR-A1",0,"",""},{"JR-B1",0,"",""},{"JR-C1",0,"",""},{"JR-A2",0,"",""},{"JR-B2",0,"",""},{"JR-C2",0,"",""},{"JR-A3",0,"",""},{"JR-B3",0,"",""},{"JR-C3",0,"",""},{"JR-A4",0,"",""},{"JR-B4",0,"",""},{"JR-C4",0,"",""}
};void showMenu(void);
char getCz(void);
char * s_gets(char * st, int n);
void functionA();
void functionB();
void functionC();
void functionD();
void functionE();int main(void){char ch;printf("巨人航空公司欢迎您,请选择您要办理的业务\n");showMenu();ch = getCz();while (getchar() != '\n')continue;while (ch != 'f'){switch (ch){case 'a':functionA();break;case 'b':functionB();break;case 'c':functionC();break;case 'd':functionD();break;case 'e':functionE();break;default:break;}showMenu();ch = getCz();while (getchar() != '\n')continue;}printf("Done!!!\n");return 0;
}
void showMenu(void){printf("-------------------------菜单-------------------------\n");printf("请选择要进行的操作,输入其字母标签\n");printf("a)显示空座位数 b)显示空座位列表 \n");printf("c)显示按字母顺序排列的座位列表 d)为客户分配座位 \n");printf("e)删除座位分配 f)退出 \n");printf("------------------------------------------------------\n");
}
char getCz(void){char input;while (scanf("%c",&input)!=1||(input != 'a'&&input != 'b'&&input != 'c'&&input != 'd'&&input != 'e'&&input != 'f')){printf("您输入的值不合法,请重新输入!!\n");while (getchar() != '\n')continue;}return input;
}
char * s_gets(char * st, int n)
{char * ret_val;char * find;ret_val = fgets(st, n, stdin);if (ret_val){find = strchr(st, '\n'); // 查找换行符if (find) // 如果地址不是 NULL,*find = '\0'; // 在此处放置一个空字符elsewhile (getchar() != '\n')continue; // 清理输入行}return ret_val;
}
void functionA(){int number = 0;for (int i = 0; i < SEATNUMBER; i++){if (seats[i].flag == 0){number++;}}printf("当前航班上还有%d个座位没有被预定\n",number);
}
void functionB(){int number = 0;printf("当前航班上空座位列表如下:\n");for (int i = 0; i < SEATNUMBER; i++){if (seats[i].flag == 0){number++;printf("%2d)%s\n",number,seats[i].number);}}
}
void functionC(){struct seat copy[SEATNUMBER];struct seat cc;for (int i = 0; i < SEATNUMBER; i++){copy[i] = seats[i];}for (int i = 0; i < SEATNUMBER; i++){for (int j = i + 1; j < SEATNUMBER; j++){if (strcmp(copy[i].number,copy[j].number) > 0){cc = copy[i];copy[i] = copy[j];copy[j] = cc;}}}int number = 0;for (int i = 0; i < SEATNUMBER; i++){number++;if (copy[i].flag == 1){printf("%2d)%s 已预订\n",number,copy[i].number);}else{printf("%2d)%s 可预订\n",number,copy[i].number);} }
}
void functionD(){int count = 0;printf("请为客户分配座位,输入空行结束\n");printf("请输入客户的名字\n");while (count < SEATNUMBER && s_gets(seats[count].ming, SIZE) != NULL &&seats[count].ming[0] != '\0' &&seats[count].flag != 1){printf("请输入客户的姓氏\n");s_gets(seats[count].xing, SIZE);seats[count].flag = 1;count++;printf("这位客户的座位已经分配好,请输入下一位客户的信息\n");}printf("座位分配结束或者座位已满\n");
}
void functionE(){int count = 0;int number = 0;char yn;printf("请开始删除座位分配\n");while (count < SEATNUMBER){if (seats[count].flag == 1){number++;printf("%2d) %s 已预订 %s %s\n",number,seats[count].number,seats[count].ming,seats[count].xing);printf("是否删除该座位分配(y/n):\n");scanf("%c",&yn);while (getchar() != '\n')continue;if (yn == 'y'){seats[count].flag = 0;} }count++;}
}
ok,我们依次进行了每个菜单的功能演示,从展示空座位列表,到预订,然后再次展示空座位数以及空座位列表,然后删除预订之后,再次展示空座位数以及空座位列表,没有问题,小细节可以优化的部分暂时不唠了,毕竟这一章的编程练习搞了好长时间了,还没有搞完。接下来,我们来看第九题的要求。将第八题扩展为可以满足四个航班,下面我们看一下程序实现以及运行结果:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define SEATNUMBER 12
#define SIZE 44
struct seat
{char number[SIZE];int flag;//0表示没有被预定,1表示已经被预定char ming[SIZE];char xing[SIZE];
};
struct seat seats[SEATNUMBER] = {{"JR-A1",0,"",""},{"JR-B1",0,"",""},{"JR-C1",0,"",""},{"JR-A2",0,"",""},{"JR-B2",0,"",""},{"JR-C2",0,"",""},{"JR-A3",0,"",""},{"JR-B3",0,"",""},{"JR-C3",0,"",""},{"JR-A4",0,"",""},{"JR-B4",0,"",""},{"JR-C4",0,"",""}
};
char hb[4][SIZE] = {"巨航102","巨航311","巨航444","巨航519"
};void showHb(void);
void showMenu(int hbn);
char getCz(void);
char * s_gets(char * st, int n);
void functionA(int hbn);
void functionB(int hbn);
void functionC(int hbn);
void functionD(int hbn);
void functionE(int hbn);
void functionF(int hbn);int main(void){char ch;char hh;printf("巨人航空公司欢迎您,请选择您要办理的业务\n");showHb();hh = getCz();while (getchar() != '\n')continue;while (hh != 'f'){int hbn = (int)hh - (int)'a';showMenu(hbn);ch = getCz();while (getchar() != '\n')continue;while (ch != 'g'){switch (ch){case 'a':functionA(hbn);break;case 'b':functionB(hbn);break;case 'c':functionC(hbn);break;case 'd':functionD(hbn);break;case 'e':functionE(hbn);break;case 'f':functionF(hbn);break;default:break;}showMenu(hbn);ch = getCz();while (getchar() != '\n')continue;}showHb();hh = getCz();while (getchar() != '\n')continue;}printf("Done!!!\n");return 0;
}
void showHb(void){char n = 'a';printf("-----------------------航班信息------------------------\n");for (int i = 0; i < 4; i++){printf("%c) %s\n",n,hb[i]);n++;}printf("%c) 退出程序\n",n);printf("-------------------------------------------------------\n");
}
void showMenu(int hbn){printf("------------------%s-----菜单-------------------------\n",hb[hbn]);printf("请选择要进行的操作,输入其字母标签\n");printf("a)显示空座位数 b)显示空座位列表 \n");printf("c)显示按字母顺序排列的座位列表 d)为客户分配座位 \n");printf("e)删除座位分配 f)确认座位分配 \n");printf("g)退出 \n");printf("------------------------------------------------------\n");
}
char getCz(void){char input;while (scanf("%c",&input)!=1 || input < 'a' || input > 'g'){printf("您输入的值不合法,请重新输入!!\n");while (getchar() != '\n')continue;}return input;
}
char * s_gets(char * st, int n)
{char * ret_val;char * find;ret_val = fgets(st, n, stdin);if (ret_val){find = strchr(st, '\n'); // 查找换行符if (find) // 如果地址不是 NULL,*find = '\0'; // 在此处放置一个空字符elsewhile (getchar() != '\n')continue; // 清理输入行}return ret_val;
}
void functionA(int hbn){int number = 0;for (int i = 0; i < SEATNUMBER; i++){if (seats[i].flag == 0){number++;}}printf("%s航班上还有%d个座位没有被预定\n",hb[hbn],number);
}
void functionB(int hbn){int number = 0;printf("%s航班上空座位列表如下:\n",hb[hbn]);for (int i = 0; i < SEATNUMBER; i++){if (seats[i].flag == 0){number++;printf("%2d)%s %s\n",number,hb[hbn],seats[i].number);}}
}
void functionC(int hbn){struct seat copy[SEATNUMBER];struct seat cc;for (int i = 0; i < SEATNUMBER; i++){copy[i] = seats[i];}for (int i = 0; i < SEATNUMBER; i++){for (int j = i + 1; j < SEATNUMBER; j++){if (strcmp(copy[i].number,copy[j].number) > 0){cc = copy[i];copy[i] = copy[j];copy[j] = cc;}}}int number = 0;for (int i = 0; i < SEATNUMBER; i++){number++;if (copy[i].flag == 1){printf("%2d) %s %s 已预订\n",number,hb[hbn],copy[i].number);}else{printf("%2d) %s %s 可预订\n",number,hb[hbn],copy[i].number);} }
}
void functionD(int hbn){int count = 0;printf("请为客户在航班%s上分配座位,输入空行结束\n",hb[hbn]);printf("请输入客户的名字\n");while (count < SEATNUMBER && s_gets(seats[count].ming, SIZE) != NULL &&seats[count].ming[0] != '\0' &&seats[count].flag != 1){printf("请输入客户的姓氏\n");s_gets(seats[count].xing, SIZE);seats[count].flag = 1;count++;printf("这位客户的座位已经分配好,请输入下一位客户的信息\n");}printf("%s航班座位分配结束或者座位已满\n",hb[hbn]);
}
void functionE(int hbn){int count = 0;int number = 0;char yn;printf("请开始删除%s航班上的座位分配\n",hb[hbn]);while (count < SEATNUMBER){if (seats[count].flag == 1){number++;printf("%2d) %s %s 已预订 %s %s\n",number,seats[count].number,hb[hbn],seats[count].ming,seats[count].xing);printf("是否删除该座位分配(y/n):\n");scanf("%c",&yn);while (getchar() != '\n')continue;if (yn == 'y'){seats[count].flag = 0;} }count++;}
}
void functionF(int hbn){int count = 0;int number = 0;char yn;printf("请开始确认%s航班上的座位分配\n",hb[hbn]);while (count < SEATNUMBER){if (seats[count].flag == 1){number++;printf("%2d) %s %s 已预订 %s %s\n",number,seats[count].number,hb[hbn],seats[count].ming,seats[count].xing);printf("是否确认该座位分配(y/n):\n");scanf("%c",&yn);while (getchar() != '\n')continue;if (yn == 'y'){seats[count].flag = 1;}else{seats[count].flag = 0;} }count++;}
}
上面,我们依次展示航班,菜单,展示空座位数以及空座位列表,然后为用户预订座位,然后在确认座位的时候一个确认,一个不进行确认,再次展示空座位数以及空座位列表,接着退出菜单,再次退出程序,结束程序。接着,我们再看一下第十题要求我们做一些什么操作。编写一个程序,通过函数指针数组去实现菜单,然后选择菜单中的值,激活对应的函数。我们简单的去实现一下这个思想要求的内容,所以具体的函数没有使用复杂的。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>void showMenu(void);
char getCz(void);
void functionA(void);
void functionB(void);
void functionC(void);int main(void){void (* ptr[3]) (void) = {functionA,functionB,functionC};char ch;showMenu();ch = getCz();while (getchar() != '\n')continue;while (ch != 'd'){int n = (int)ch - (int)'a';switch (ch){case 'a':ptr[n]();break;case 'b':ptr[n]();break;case 'c':ptr[n]();break;default:break;}showMenu();ch = getCz();while (getchar() != '\n')continue;}return 0;
}
void showMenu(void){printf("------------------------------------------\n");printf("a) 方法A \n");printf("b) 方法B \n");printf("c) 方法C \n");printf("d) 退出 \n");printf("------------------------------------------\n");
}
char getCz(void){char input;while (scanf("%c",&input)!=1 || input < 'a' || input > 'd'){printf("您输入的值不合法,请重新输入!!\n");while (getchar() != '\n')continue;}return input;
}
void functionA(void){printf("-------------方法A开始运行----------------\n");printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");printf("-------------方法A结束运行----------------\n");
}
void functionB(void){printf("-------------方法B开始运行----------------\n");printf("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n");printf("-------------方法B结束运行----------------\n");
}
void functionC(void){printf("-------------方法C开始运行----------------\n");printf("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n");printf("-------------方法C结束运行----------------\n");
}
接着,我们再看一下本章的最后一个编程练习的要求,编写一个函数,函数名已经给了我们,所接受的四个参数也已经规定了,分别是,内含double数据的源数组名、内含double数据的目标数组名、表示数组元素个数的int数据、函数指针。函数把指定函数应用于源数组的每个元素,将返回值放到目标数组之中,测试该函数四次,使用两个math.h中的函数,两个自定义的函数。下面看一下完整程序以及运行结果:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#define SIZE 40
void transform(const double * trage,double * source,int count,double (* ptr)(double));
double functionE(double n);
double functionD(double n);
void showArr(const double * ac,int n);
int main(void){double arr[SIZE];for (int i = 0; i < SIZE; i++){arr[i]= i;}double ac[SIZE];printf("--------第一次调用-------------\n");transform(arr,ac,SIZE,sin);showArr(ac,SIZE);printf("--------第二次调用-------------\n");transform(arr,ac,SIZE,cos);showArr(ac,SIZE);printf("--------第三次调用-------------\n");transform(arr,ac,SIZE,functionE);showArr(ac,SIZE);printf("--------第四次调用-------------\n");transform(arr,ac,SIZE,functionD);showArr(ac,SIZE);return 0;
}
void transform(const double * source,double * trage,int count,double (* ptr)(double)){for (int i = 0; i < count; i++){*(trage + i) = ptr(*(source + i));}
}
double functionE(double n){double r;r = 2*n;return r;
}
double functionD(double n){double r;r = 1/n;return r;
}
void showArr(const double * ac,int n){for (int i = 0; i < n; i++){printf("%.2f ",*(ac+i));if (i%9==0 && i != 0){printf("\n");} } printf("\n");
}
最后一个问题并不是很麻烦,在实现的时候呢,我们先是调用了math.h中的sin()函数和cos()函数,然后自己写了两个函数,分别求取值的二倍以及倒数,分别调用并展示处理之后得到的数据。以上就是本章的编程练习,总体来说还是比较有东西的,毕竟搞了这么好几天呢。第十四章暂时告一段落,接着,我们就要去看一下书上关于第十五章位操作的内容了。
这篇关于C Primer Plus第十四章编程练习,仅供参考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!