当前位置: 首页 > news >正文

《C Primer Plus》中文版第十四章习题

14.17 复习题

1. 下面的结构模板有什么问题:

答案:

a. 正确的关键字是struct,不是structure。

b. togs和模板后面少一个分号

正确版本:

struct house
{char itable;int num[20];char* togs;
};

2. 下面是程序的一部分,输出是什么?

#include <stdio.h>
struct house
{float sqft;int rooms;int stories;char address[40];
};
int main(void)
{struct house frust = { 1560.0, 6, 1, "22 Spiffo Road" };struct house* sign;sign = &frust;printf("%d %d\n", frust.rooms, sign->stories);printf("%s\n", frust.address);printf("%c %c\n", sign->address[3] , sign->address[4]);return 0;
}

答案:

3. 设计一个结构模板储存一个月份名、该月份名的三个字母缩写、该月的天数以及月份号。

struct month
{char name[10];char abbrev[4];int days;int monumb;
};

4. 定义一个数组,内含12个结构(第3题的结构类型)并初始化为一个年份(非闰年)。

struct month
{char name[10];char abbrev[4];int days;int monumb;
};
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 }
};

5. 编写一个函数,用户提供月份号,该函数就返回一年中到该月为止(包括该月)的总天数。假设在所有函数的外部声明了第3题的结构模板和一个该类型的数组。

#include <stdio.h>
#include <stdlib.h>
struct month
{char name[10];char abbrev[4];int days;int monumb;
};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 main(void)
{int currentMonth = 0, totalDay = 0;printf("Input current month: ");scanf_s("%d", &currentMonth);if (currentMonth < 1 || currentMonth > 12) {printf("month should range from 1 to 12\n");exit(EXIT_FAILURE);}for (int i = 0; i < currentMonth; i++)totalDay += months[i].days;printf(" 0 - %d months has %d days\n", currentMonth, totalDay);return 0;
}

6. a. 假设有下面的typedef,声明一个内含10个指定结构的数组。然后,单独给成员赋值(或等价字符串),使第3个元素表示一个表示焦距长度500mm,孔径为f/2.0的Remarkata镜头。

typedef struct lens { /*描述镜头*/float foclen;     /*焦距长度,单位为mm*/float fstop;      /*孔径*/char brand[30];   /*品牌名称*/
} LENS;

b. 重写a,在声明中使用一个待指定初始化器的初始化列表,而不是对每个成员单独赋值。

答案:

a.

#include <stdio.h>
#include <string.h>
typedef struct lens {float foclen;float fstop;char brand[30];
} LENS;
int main()
{LENS lensArray[10];lensArray[2].fstop = 500;lensArray[2].foclen = 2.0;strcpy_s(lensArray[2].brand, "Remarkata");printf("fstop: %.2f, foclen: %.2f, brand: %s\n", lensArray[2].fstop, lensArray[2].foclen, lensArray[2].brand);
}

b.

#include <stdio.h>
#include <string.h>
typedef struct lens {float foclen;float fstop;char brand[30];
} LENS;
int main()
{LENS lensArray[10];lensArray[2] = { 2.0, 500, "Remarkata"};printf("fstop: %.2f, foclen: %.2f, brand: %s\n", lensArray[2].fstop, lensArray[2].foclen, lensArray[2].brand);
}

7. 考虑下面程序片段:

#include <stdio.h>
void printBem(const struct bem* pb);
struct name {char first[20];char last[20];
};
struct bem {int limbs;struct name title;char type[30];
};
struct bem* pb;
struct bem deb = {6,{ "Berbnazel", "Gwolkapwolk"},"Arcturan"
};
int main(void)
{pb = &deb;printf("%d\n", deb.limbs);printf("%s\n", pb->type);printf("%s\n", pb->type + 2);printf("%s\n", deb.title.last);printf("%s\n", pb->title.last);printBem(pb);return 0;
}
void printBem(const struct bem * pb)
{printf("%s %s is a %d-limed %s\n", pb->title.first, pb->title.last, pb->limbs, pb->type);
}

a. 下面的语句分别打印什么?

	printf("%d\n", deb.limbs);printf("%s\n", pb->type);printf("%s\n", pb->type + 2);

b. 如何用结构表示法(两种方法)表示"Gwolkapwolk"?

c. 编写一个函数,以bem结构的地址作为参数,并下面的形式输出结构的内容(假定结构模板在一个名为starfolk.h的头文件中):

Benbnazel Gwolkapwolk is a 6-limbed Arcturan.

答案:

a.

b.

	printf("%s\n", deb.title.last);printf("%s\n", pb->title.last);

c.

void printBem(const struct bem * pb)
{printf("%s %s is a %d-limed %s\n", pb->title.first, pb->title.last, pb->limbs, pb->type);
}

8. 考虑下面的声明:

#include <stdio.h>
#include <string.h>
struct fullname {char fname[20];char lname[20];
};
struct bard {struct fullname name;int born;int died;
};
struct bard willie;
struct bard* pt = &willie;
int main(void)
{willie = { {"Polly", "Poetics"}, 2000, 2010};printf("born is: %d\n", willie.born);printf("born is: %d\n", pt->born);printf("Please input born:");scanf_s("%d", &willie.born);printf("Now born is: %d\n", willie.born);printf("Please input born:");scanf_s("%d", &pt->born);printf("Now born is: %d\n", pt->born);printf("Please input lname:");scanf_s("%s", willie.name.lname, sizeof(willie.name.lname));printf("Now lname is: %s\n",willie.name.lname);printf("Please input lname:");scanf_s("%s", pt->name.lname, sizeof(pt->name.lname));printf("Now lname is: %s\n", pt->name.lname);printf("third character is :%c\n", willie.name.fname[2]);printf("total letters is: %d\n",(strlen(willie.name.fname) + strlen(willie.name.lname)));return 0;
}

a. 用willie标识符标识willie结构的born成员。

b. 用pt标识符标识willie结构的born成员。

c. 调用scanf()读入一个用willie标识符标识的born成员。

d. 调用scanf()读入一个用pt标识符标识的born成员。

e. 用scanf()读入一个用willie标识符标识的name成员的lname成员的值。

f. 用scanf()读入一个用pt标识符标识的name成员的lname成员的值。

g. 构建一个标识符,标识willie结构变量所表示的姓名中名的第3个字母(英文的名在前面)。

h. 构造一个表达式,表示willie结构变量所表示的名和姓中的字母总数。

答案:

a. willie.born

b. pt->born

c. scanf_s("%d", &willie.born);

d. scanf_s("%d", &pt->born);

e. scanf_s("%s", willie.name.lname, sizeof(willie.name.lname));

f. scanf_s("%s", pt->name.lname, sizeof(pt->name.lname));

g. printf("third character is :%c\n", willie.name.fname[2]);

h. printf("total letters is: %d\n",(strlen(willie.name.fname) + strlen(willie.name.lname)));

9. 定义一个结构模板以储存这些项:汽车名、马力、EPA(美国环保局)城市交通MPG(每加仑燃料行驶的英里数)评级、轴距和出厂年份。使用car作为该模板的标记。

struct car
{char name[20];float horsepower;float epampg;float wheelbase;int year;
};

 10. 假设有如下结构:

#include <stdio.h>
struct gas {float distance;float gals;float mpg;
};
struct gas mpgsOne(struct gas trip);
void setMpg(struct gas* ptrip);
int main()
{struct gas idaho = {430, 14.0};idaho = mpgsOne(idaho);printf("%.2f %.2f %.2f\n",idaho.distance, idaho.gals, idaho.mpg);struct gas odaho = { 538, 17.6 };setMpg(&odaho);printf("%.2f %.2f %.2f\n", odaho.distance, odaho.gals, odaho.mpg);return 0;
}
struct gas mpgsOne(struct gas trip)
{if (trip.gals > 0)trip.mpg = trip.distance / trip.gals;elsetrip.mpg = -1;return trip;
}
void setMpg(struct gas * ptrip)
{if (ptrip->gals > 0)ptrip->mpg = ptrip->distance / ptrip->gals;elseptrip->mpg = -1;
}

a. 设计一个函数,接受struct gas类型的参数。假设传入的结构包含distance和gals信息。该函数为mpg成员计算正确的值,并把值返回该结构。

b. 设计一个函数,接受struct gas类型的参数。假设传入的结构包含distance和gals信息。该函数为mpg成员计算正确的值,并把该值赋给合适的成员。

答案:

a.

struct gas mpgsOne(struct gas trip)
{if (trip.gals > 0)trip.mpg = trip.distance / trip.gals;elsetrip.mpg = -1;return trip;
}

b.

void setMpg(struct gas * ptrip)
{if (ptrip->gals > 0)ptrip->mpg = ptrip->distance / ptrip->gals;elseptrip->mpg = -1;
}

11. 声明一个标记为choices的枚举,把枚举常量no、yes和maybe分别设置为0、1、2。

答案:

enum choices
{no,yes,maybe 
};

12. 声明一个指向函数的指针,该函数返回指向char的指针,接受一个指向char的指针和一个char类型的值。

答案:

char* (*fp)(char * pOne, char ch);

13. 声明4个函数,并初始化一个指向这些函数的指针数组。每个函数都接受两个double类型的参数,返回double类型的值。另外,用两种方法使用该数组调用带10.0和2.5两个实参的第2个函数。

#include <stdio.h>
double sum(double numOne,double numTwo);
double diff(double numOne, double numTwo);
double times(double numOne, double numTwo);
double divide(double numOne, double numTwo);
int main(void)
{double (*pf[4])(double numOne, double numTwo) = {sum , diff, times, divide};double result = pf[1](10.0, 2.5);printf("result is: %.2lf\n", result);return 0;
}
double sum(double numOne, double numTwo)
{return numOne + numTwo;
}
double diff(double numOne, double numTwo)
{return numOne - numTwo;
}
double times(double numOne, double numTwo)
{return numOne * numTwo;
}
double divide(double numOne, double numTwo)
{return numOne / numTwo;
}

14.18 编程练习

1. 重新编写复习题5,用月份名的拼写代替月份号(别忘了使用strcmp())。在一个简单的程序中测试该函数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct month
{char name[10];char abbrev[4];int days;int monumb;
};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 main(void)
{int totalDay = 0, currentMonth = 0;char monthName[20];printf("Input current month name: ");scanf_s("%s", monthName, sizeof(monthName));for (int i = 0; i < 12; i++){totalDay += months[i].days;if (strcmp(months[i].abbrev, monthName) == 0){currentMonth = months[i].monumb;break;}}printf(" 1 - %d months has %d days\n", currentMonth, totalDay);return 0;
}

2. 编写一个函数,提示用户输入日、月和年。月份可以是月份号、月份名或月份名缩写。然后该程序应返回一年中到用户指定日子(包括这一天)的总天数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct month
{char name[10];char abbrev[4];int days;int monumb;
};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 main(void)
{int totalDay = 0, currentMonth = 0;char monthName[20];int year, day;printf("Enter the YEAR MONTH DAY (seprate by blank): ");scanf_s("%d %s %d", &year, monthName, sizeof(monthName), &day);if (day < 1 || day > 31){printf("days should range from 1 to 31.");exit(EXIT_FAILURE);}for (int i = 0; i < 12; i++){if ((months[i].monumb == atoi(monthName)) || (strcmp(months[i].abbrev, monthName) == 0) || (strcmp(months[i].name, monthName) == 0)){totalDay += day;currentMonth = months[i].monumb;break;}else{totalDay += months[i].days;}}printf("The %d/%s/%d has %d days\n",year, monthName, day, totalDay);return 0;
}

3. 修改程序清单14.2中的图书目录程序,使其按照输入图书的顺序输出图书的信息,然后按照标题字母的声明输出图书的信息,最后按照价格的升序输出图书的信息。

#include <stdio.h>
#include <string.h>
#define MAXTITLE 41
#define MAXAUTHOR 31
#define MAXBOOKS 2
struct book {char title[MAXTITLE];char author[MAXAUTHOR];float value;
};
char* s_gets(char* st, int n);
void listBook(struct book library[], int count);
void listBookTitle(struct book library[], int count);
void listBookValue(struct book library[], int count);
int main(void)
{struct book library[MAXBOOKS];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 < MAXBOOKS && s_gets(library[count].title, MAXTITLE) != NULL && library[count].title[0] != '\0'){printf("Now enter the author.\n");s_gets(library[count].author, MAXAUTHOR);printf("Now enter the value.\n");scanf_s("%f", &library[count++].value);while (getchar() != '\n')continue;if (count < MAXBOOKS)printf("Enter the next tilte.\n");}if (count > 0){listBook(library, count);listBookTitle(library, count);listBookValue(library, count);}elseprintf("No books? Too bad.\n");printf("Done.\n");return 0;
}
void listBook(struct book library[], int count)
{printf("Here is the list of your books:\n");for (int index = 0; index < count; index++)printf("%s by %s: $%0.2f\n", library[index].title, library[index].author, library[index].value);
}
void listBookTitle(struct book library[], int count)
{char* ptitle[400];char* temp;int top, seek;for (int index = 0; index < count; index++)ptitle[index] = library[index].title;for (top = 0; top < count; top++){for (seek = 0; seek < count - top - 1; seek++){if (strcmp(ptitle[seek], ptitle[seek + 1]) > 0){temp = ptitle[seek];ptitle[seek] = ptitle[seek + 1];ptitle[seek + 1] = temp;}}}printf("Here is the list of your books by title:\n");for (int index = 0; index < count; index++){for (int i = 0; i < count; i++){if (ptitle[index] == library[i].title){printf("%s by %s: $%0.2f\n", library[i].title, library[i].author, library[i].value);break;}}}
}
void listBookValue(struct book library[], int count)
{float* pvalue[400];float* temp;int top, seek;for (int index = 0; index < count; index++)pvalue[index] = &library[index].value;for (top = 0; top < count; top++){for (seek = 0; seek < count - top - 1; seek++){if (*pvalue[seek]> *pvalue[seek + 1]){temp = pvalue[seek];pvalue[seek] = pvalue[seek + 1];pvalue[seek + 1] = temp;}}}printf("Here is the list of your books by value:\n");for (int index = 0; index < count; index++){for (int i = 0; i < count; i++){if (*pvalue[index] == library[i].value){printf("%s by %s: $%0.2f\n", library[i].title, library[i].author, library[i].value);break;}}}
}
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)*find = '\0';elsewhile (getchar() != '\n')continue;}return ret_val;
}

4. 编写一个程序,创建一个有两个成员的结构模板:

a. 第1个成员是社会保险号,第2个成员是一个有3个成员的结构,第1个成员代表名,第2个成员代表中间名,第3个成员表示姓。创建并初始化一个内含5个该类型结构的数组。该程序以下面的格式打印数据:

Dribble, Flossie M. - - 302039823

如果有中间名,只打印它的第1个字母,后面加一个点(.);如果没有中间名,则不用打印点。编写一个程序进行打印,把结构数组传递给这个函数。

b. 修改a部分,传递结构的值而不是结构的地址。

答案:

a.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct user {char fname[15];char mname[15];char lname[15];
};
struct userId {char sid[30];struct user name;
};
void printUserId(struct userId user);
int main(void)
{struct userId userList = { "302039823", {"Flossie", "Mike", "Dribble"} };printf("Test to print struct contents:\n");printUserId(userList);return 0;
}
void printUserId(struct userId user)
{printf("%s, ", user.name.lname);printf(" %s ", user.name.fname);if (strlen(user.name.mname) > 0)printf("%c. ", user.name.mname[0]);printf("-- %s", user.sid);printf("\n");
}

b.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct user {char fname[15];char mname[15];char lname[15];
};
struct userId {char sid[30];struct user name;
};
void printUserId(struct userId user);
int main(void)
{struct userId userList = { "302039823", {"Flossie", "Mike", "Dribble"} };printf("Test to print struct contents:\n");printUserId(userList);return 0;
}
void printUserId(struct userId user)
{printf("%s, ", user.name.lname);printf(" %s ", user.name.fname);if (strlen(user.name.mname) > 0)printf("%c. ", user.name.mname[0]);printf("-- %s", user.sid);printf("\n");
}

5. 编写一个程序满足下面的要求:

a. 外部定义一个有两个成员的结构模板name:一个字符串储存名,一个字符串储存姓。

b. 外部定义一个有3个成员的结构模板student:一个name类型的结构,一个grade数组储存3个浮点型分数,一个变量储存3个分数平均数。

c. 在main()函数中声明一个内含CSZIE(CSZIE = 4)个student类型结构的数组,并初始化这些结构的名字部分。用函数执行g、e、f和g中描述的任务。

d. 以交互的方式获取每个学生的成绩,提示用户输入学生的姓名和分数。把分数储存到grade数组相应的结构中。可以在main()函数或其他函数中用循环来完成。

e. 计算每个结构的平均分,并把计算后的值赋给合适的成员。

f. 打印每个结构的信息。

g. 打印班级的平均分,即所有结构的数值成员的平均分。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person {char fname[40];char lname[40];
};
struct student {struct person name;float grade[3];float average;
};
#define CSIZE 2
void setGrade(struct student list[]);
void setAverage(struct student list[]);
void printAllInfo(struct student list[]);
void printAllAverage(struct student list[]);
int main()
{struct student list[CSIZE];setGrade(list);setAverage(list);printAllInfo(list);printAllAverage(list);return 0;
}
void setGrade(struct student list[])
{char fname[15], lname[15];for (int i = 0; i < CSIZE; i++){printf("Enter the student name(firstname lastname):");scanf_s("%s %s", fname, sizeof(fname), lname, sizeof(lname));strcpy_s(list[i].name.fname, fname);strcpy_s(list[i].name.lname, lname);printf("Enter the 3 score of %s:", fname);scanf_s("%f %f %f", &list[i].grade[0], &list[i].grade[1], &list[i].grade[2]);}
}
void setAverage(struct student list[])
{for (int i = 0; i < CSIZE; i++){list[i].average = (list[i].grade[0] + list[i].grade[1] + list[i].grade[2]) / 3;}
}
void printAllInfo(struct student list[])
{for (int i = 0; i < CSIZE; i++){printf("No.%d: %s.%s : %5.2f %5.2f %5.2f, average = %5.2f\n", i, list[i].name.fname, list[i].name.lname,list[i].grade[0], list[i].grade[1], list[i].grade[2], list[i].average);}
}
void printAllAverage(struct student list[])
{float sum = 0.0;for (int i = 0; i < CSIZE; i++){sum += list[i].average;}printf("All average is %.2f\n", sum / CSIZE);
}

6. 一个文本文件中保存着一个垒球队的信息。每行数据都是这样排列:

4 Jessie Joybat 5 2 1 1

第1项是球员号,为方便起见,其范围是0~18。第2项是球员的名。第3项是球员的姓。名和姓都是一个单词。第4项是官方统计的球员上场次数。接着3项分别是击中数、走垒数和打点(RBI)。文件可能包含多场比赛的数据,所以同一位球员可能有多行数据,而且同一位球员的多行数据之间可能有其他球员的数据。编写一个程序,把数据储存到一个结构数组中。该结构中的成员要分别表示球员的名、姓、上次次数、击中数、走垒数、打点和安达率(稍后计算)。可以使用球员号作为数组的索引。该程序要读到文件结尾,并统计每位球员的各项累计之和。

世界棒球统计与之相关。例如,一次走垒和触垒中的失误不计入上场次数,但是可能产生一个RBI。但是该程序要做的是像下面描述的一样读取和处理数据文件,不会关心数据的实际含义。

要实现这些功能,最简单的方法是把结构的内容都初始化为零,把文件中的数据读入临时变量中,然后将其加入相应的结构中。程序读完文件后,应计算每位球员的安打率,并把计算结果储存到结构的相应成员中。计算安达率是用球员的累计击中数除以上场累计次数。这是一个浮点数计算。最后,程序结合整个球队的统计数据,一行显示一位球员的累计数据。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct  {int id;char fname[20];char lname[20];int startNum;int hitNum;int baseNum;int RBI;float BABIP;
} PLAYER;
void readData(PLAYER players[], FILE* fp);
void setBabip(PLAYER players[]);
void printInfo(PLAYER players[]);
int main(void)
{PLAYER players[19] = {};FILE* fp;if ((fopen_s(&fp, "dataOne.txt", "r") != 0) || fp == NULL){fprintf(stderr, "Can't open %s\n", "dataOne.txt");exit(EXIT_FAILURE);}readData(players, fp);setBabip(players);printInfo(players);fclose(fp);return 0;
}
void readData(PLAYER players[], FILE* fp)
{if (fp == NULL){printf("Can not open the file.\n");exit(EXIT_FAILURE);}int id, startNum, hitNum, baseNum, RBI;float BABIP;char fname[20], lname[20];int readCount = 1;while (1){readCount = fscanf_s(fp, "%d %s %s %d %d %d %d", &id, fname, sizeof(fname), lname, sizeof(lname), &startNum, &hitNum, &baseNum, &RBI);if (readCount < 7)break;strcpy_s(players[id].fname, fname);strcpy_s(players[id].lname, lname);players[id].id = id;players[id].startNum += startNum;players[id].hitNum += hitNum;players[id].baseNum += baseNum;players[id].RBI += RBI;}
}
void setBabip(PLAYER players[])
{for (int i = 0; i < 19; i++){if (players[i].hitNum != 0 && players[i].startNum != 0){players[i].BABIP = (float)players[i].hitNum / (float)players[i].startNum;}}
}
void printInfo(PLAYER players[])
{printf("ID: FIRST_NAME.LAST_NAME START HIT_NUM BASE_NUM RBI BABAIP\n");for (int i = 0; i < 19; i++){printf("%2d %10s.%-10s %5d %5d %7d %6d %.2f\n", players[i].id, players[i].fname, players[i].lname,players[i].startNum,players[i].hitNum, players[i].baseNum, players[i].RBI, players[i].BABIP);}
}

7. 修改程序清单14.14,从文件中读取每条记录并显示出来,允许用户删除记录或修改记录的内容。如果删除记录,把空出来的空间留给下一个要读入的记录。要修改现有的文件内容,必须使用"r+b"模式,而不是"a+b"模式。而且,必须更加注意定位文件指针,防止新加入的记录覆盖现有记录。最简单的方法是改动储存在内存中的所有数据,然后再把最后的信息写入文件。跟踪的一个方法是在book结构中添加一个成员表示是否该项被删除。

#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
{char title[MAXTITL];char author[MAXAUTL];float value;int deleteFlag;
};
int main(void)
{struct book library[MAXBKS];int count = 0;int index, filecount;FILE* pbooks;int size = sizeof(struct book);char modifyChoice, deleteChoice;if (fopen_s(&pbooks, "book.dat", "r+b") != 0 || pbooks == NULL){fputs("Can't open book.dat file\n", stderr);exit(EXIT_FAILURE);}rewind(pbooks);while (count < MAXBKS && fread(&library[count], size, 1, pbooks) == 1){if (count == 0)puts("Current contents of book.dat:");printf("%s by %s: %.2f\n", library[count].title, library[count].author, library[count].value);count++;}filecount = count;if (count == MAXBKS){fputs("The book.dat file is full.", stderr);exit(EXIT_FAILURE);}printf("Do you want to modify library?(y/n):");scanf_s("%c", &modifyChoice, sizeof(modifyChoice));if (modifyChoice == 'y'){for (int i = 0; i < count; i++){printf("%s by %s: %.2f\n", library[i].title, library[i].author, library[i].value);while (getchar() != '\n')continue;puts("Do you want to delete this book?(y/n):");scanf_s("%c", &deleteChoice, sizeof(deleteChoice));if (deleteChoice == 'y')library[i].deleteFlag = 1;}}while (getchar() != '\n')continue;puts("Please add new book titles.");puts("Press [enter] at the start of a line to stop.");while (count < 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_s("%f", &library[count].value);library[count++].deleteFlag = 0;while (getchar() != '\n')continue;if (count < MAXBKS)puts("Enter the next title.");}freopen_s(&pbooks,"book.dat", "wb", pbooks);rewind(pbooks);if (count > 0){puts("Here is the list of your books:");for (index = 0; index < count; index++){if (library[index].deleteFlag != 1){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)*find = '\0';elsewhile (getchar() != '\n')continue;}return ret_val;
}

8. 巨人航空公司的机群由12个座位的飞机组成。它每天飞行一个航班。根据下面的要求,编写一个座位预定程序。

a. 该程序使用一个内含12个结构的数组。每个结构中包括:一个成员表示座位编号、一个成员表示座位是否已被预订、一个成员表示预定人的名、一个成员表示预定人的姓。

b. 该程序显示下面的菜单:

To choose a function, enter its letter label:
a) Show number of empty seats
b) Show list of empty seats
c) Show alphabetical list of seats
d) Assign a customer to a seat assignment
e) Delete a seat assignment
f) Quit

c. 该程序能成功执行上面给出的菜单。选择 d)和 e)要提示用户进行额外输入,每个选项都能让用户中止输入。

d. 执行特定程序后,该程序再次显示菜单,除非用户选择 f)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{int id;int booked;char fname[20];char lname[20];
}SEAT;
SEAT list[12] = {};
#define MAXNUM 12
void showMenu();
void getEmpty(SEAT list[]);
void showEmpty(SEAT list[]);
void showBooked(SEAT list[]);
void bookSeat(SEAT list[]);
void cancelBook(SEAT list[]);
int main(void)
{char selected;showMenu();while ((selected = getchar()) != 'f'){switch (selected){case 'a':getEmpty(list);break;case 'b':showEmpty(list);break;case 'c':showBooked(list);break;case 'd':bookSeat(list);break;case 'e':cancelBook(list);break;default:break;}while (getchar() != '\n')continue;showMenu();}return 0;
}
void showMenu()
{puts("To choose a function, enter its letter label:");puts("a) Show number of empty seats");puts("b) Show list of empty seats");puts("c) Show alphabetical list of seats");puts("d) Assign a customer to a seat assignment");puts("e) Delete a seat assignment");puts("f) Quit");
}
void getEmpty(SEAT list[])
{int sum = 0;for (int i = 0; i < MAXNUM; i++){if (list[i].booked == 0){sum++;}}printf("There are %d seats empty.\n", sum);
}
void showEmpty(SEAT list[])
{printf("Empty list:");for (int i = 0; i < MAXNUM; i++){if (list[i].booked == 0)printf("%d ", i+1);}putchar('\n');
}
void showBooked(SEAT list[])
{SEAT* ptstr[MAXNUM];for (int i = 0; i < MAXNUM; i++){ptstr[i] = &list[i];}int top, seek;SEAT* temp;for (top = 0; top < MAXNUM; top++){for (seek = 0; seek < MAXNUM - top - 1; seek++){if (strcmp(ptstr[seek]->fname, ptstr[seek + 1]->fname) > 0){temp = ptstr[seek];ptstr[seek] = ptstr[seek + 1];ptstr[seek + 1] = temp;}}}puts("Alphabetical list:");for (int i = 0; i < MAXNUM; i++){if (list[i].booked == 1){printf("Seat No: %d book by %s.%s\n", (i+1), list[i].fname, list[i].lname);}}
}
void bookSeat(SEAT list[])
{int id;char fname[20], lname[20];showEmpty(list);puts("Please select the seat:");scanf_s("%d", &id);if (list[id - 1].booked == 1){puts("Error selected.");return;}list[id - 1].id = id;puts("Please input your FIRST_NAME LAST_NAME.");scanf_s("%s %s", fname, sizeof(fname), lname, sizeof(lname));strcpy_s(list[id - 1].fname, fname);strcpy_s(list[id - 1].lname, lname);list[id - 1].booked = 1;puts("Booked!");
}
void cancelBook(SEAT list[])
{showBooked(list);int id;puts("Please select the seat to cancel.");scanf_s("%d", &id);if (list[id - 1].booked == 0){puts("Error selected.");return;}list[id - 1].booked = 0;puts("Book canceled!");
}

9. 巨人航空公司(编程练习8)需要另外一架飞机(容量相同),每天飞4班(航班102、311、444和519)。把程序扩展为可以处理4个航班。用一个顶级菜单提供航班选择和退出。选择一个特定航班,就会出现和编程练习8类似的菜单。但是该菜单要添加一个新选项:确认座位分配。而且,菜单中的退出是返回顶级菜单。每次显示都要指明当前正在处理的航班号。另外,座位分配显示要指明确认状态。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {int id;int booked;char fname[20];char lname[20];
}SEAT;
SEAT list[4][12] = {};
#define MAXNUM 12
void showMenu();
void getEmpty(SEAT list[]);
void showEmpty(SEAT list[]);
void showBooked(SEAT list[]);
void bookSeat(SEAT list[]);
void cancelBook(SEAT list[]);
int main(void)
{char selected;int airNo,listNo;printf("Please select airplane No1(102, 311, 444, 519):");scanf_s("%d", &airNo);while (airNo == 102 || airNo == 311 || airNo == 444 || airNo == 519) {if (airNo == 102){printf("You are select at Air %d: \n", airNo);listNo = 0;}if (airNo == 311){printf("You are select at Air %d: \n", airNo);listNo = 1;}if (airNo == 444){printf("You are select at Air %d: \n", airNo);listNo = 2;}if (airNo == 519){printf("You are select at Air %d: \n", airNo);listNo = 3;}while (getchar() != '\n')continue;showMenu();while ((selected = getchar()) != 'f'){switch (selected){case 'a':getEmpty(list[listNo]);break;case 'b':showEmpty(list[listNo]);break;case 'c':showBooked(list[listNo]);break;case 'd':bookSeat(list[listNo]);break;case 'e':cancelBook(list[listNo]);break;default:break;}while (getchar() != '\n')continue;showMenu();}while (getchar() != '\n')continue;printf("Please select airplane No1(102, 311, 444, 519):");scanf_s("%d", &airNo);}puts("Done!");return 0;
}
void showMenu()
{puts("To choose a function, enter its letter label:");puts("a) Show number of empty seats");puts("b) Show list of empty seats");puts("c) Show alphabetical list of seats");puts("d) Assign a customer to a seat assignment");puts("e) Delete a seat assignment");puts("f) Quit");
}
void getEmpty(SEAT list[])
{int sum = 0;for (int i = 0; i < MAXNUM; i++){if (list[i].booked == 0){sum++;}}printf("There are %d seats empty.\n", sum);
}
void showEmpty(SEAT list[])
{printf("Empty list:");for (int i = 0; i < MAXNUM; i++){if (list[i].booked == 0)printf("%d ", i + 1);}putchar('\n');
}
void showBooked(SEAT list[])
{SEAT* ptstr[MAXNUM];for (int i = 0; i < MAXNUM; i++){ptstr[i] = &list[i];}int top, seek;SEAT* temp;for (top = 0; top < MAXNUM; top++){for (seek = 0; seek < MAXNUM - top - 1; seek++){if (strcmp(ptstr[seek]->fname, ptstr[seek + 1]->fname) > 0){temp = ptstr[seek];ptstr[seek] = ptstr[seek + 1];ptstr[seek + 1] = temp;}}}puts("Alphabetical list:");for (int i = 0; i < MAXNUM; i++){if (list[i].booked == 1){printf("Seat No: %d book by %s.%s\n", (i + 1), list[i].fname, list[i].lname);}}
}
void bookSeat(SEAT list[])
{int id;char fname[20], lname[20];showEmpty(list);puts("Please select the seat:");scanf_s("%d", &id);if (list[id - 1].booked == 1){puts("Error selected.");return;}list[id - 1].id = id;puts("Please input your FIRST_NAME LAST_NAME.");scanf_s("%s %s", fname, sizeof(fname), lname, sizeof(lname));strcpy_s(list[id - 1].fname, fname);strcpy_s(list[id - 1].lname, lname);list[id - 1].booked = 1;puts("Booked!");
}
void cancelBook(SEAT list[])
{showBooked(list);int id;puts("Please select the seat to cancel.");scanf_s("%d", &id);if (list[id - 1].booked == 0){puts("Error selected.");return;}list[id - 1].booked = 0;puts("Book canceled!");
}

10. 编写一个程序,通过一个函数指针数组实现菜单。例如,实现菜单中的a,将激活由该数组的第1个元素指向的函数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void functionA(char ch);
void functionB(char ch);
void functionC(char ch);
void showMenu();
int main(void)
{void (*pf[3]) (char) = { functionA , functionB, functionC };char ch;showMenu();scanf_s("%c", &ch);while (ch != 'q'){while (getchar() != '\n')continue;switch(ch){case 'a':pf[0](ch);break;case 'b':pf[1](ch);break;case 'c':pf[2](ch);break;default:break;}showMenu();scanf_s("%c", &ch);}return 0;
}
void showMenu()
{puts("a) Function A.		b) Function B.		c) Function C.		q)Quit");puts("Enter a, b, c ot q:");
}
void functionA(char ch)
{printf("This is functionA you select %c\n", ch);
}
void functionB(char ch)
{printf("This is functionB you select %c\n", ch);
}
void functionC(char ch)
{printf("This is functionC you select %c\n", ch);
}

11. 编写一个名为transform()的函数,接受4个参数:内含double类型数据的源数组名、内含double类型数据的目标数组名、一个表示数组元素个数的int类型参数、函数名(或等价的函数指针)。transform()函数应把指定函数应用于源数组中的每个元素,并把返回值储存在目标数组中。例如:

transform(source, target, 100, sin);

该声明会把target[0]设置为sin(source[0]),等等,共有100个元素。在一个程序中调用transform()4次,以测试该函数。分别使用math.h函数库中的两个函数以及自定义的两个函数作为参数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define LENGTH 10
void transform(double src[], double tar[], int n, double (*func)(double));
int main(void)
{double source[LENGTH], target[LENGTH];for (int i = 0; i < LENGTH; i++){source[i] = i;}printf("The source data is:\n");for (int i = 0; i < LENGTH; i++){printf("%5g ", source[i]);}printf("\n");transform(source, target, LENGTH, sin);printf("The target sin data is:\n");for (int i = 0; i < LENGTH; i++){printf("%5g ", target[i]);}printf("\n");transform(source, target, LENGTH, cos);printf("The target cos data is:\n");for (int i = 0; i < LENGTH; i++){printf("%5g ", target[i]);}printf("\n");return 0;
}
void transform(double src[], double tar[], int n, double (*func)(double))
{for (int i = 0; i < n; i++){tar[i] = func(src[i]);}}


http://www.mrgr.cn/news/58521.html

相关文章:

  • 太速科技-212-RCP-601 CPCI刀片计算机
  • 基于.NET 8.0,C#中Microsoft.Office.Interop.Excel来操作office365的excel
  • git 免密的方法
  • vue需要清除定时器和延时器吗
  • 基于django的网络问政管理平台
  • 使用docker-compose搭建redis7集群-3主3从
  • 深入探讨编程的核心概念、学习路径、实际应用以及对未来的影响
  • openssl 自签证书
  • FaceFusion 3.0.0: 融合未来,创造无限可能
  • 一篇文章搞懂GO并发编程!
  • 15-01 mave高级-分模块设计与开发
  • Python基础14_Pandas(下)
  • 多态(作业篇)
  • python算法学习笔记之查找算法
  • 2:ARM 汇编语言2:二进制/十进制/十六进制
  • RBM HA联动VRRP三层主备案例
  • 从天边到身边,‘湘’遇北斗,‘株’多精彩
  • 状态栏黑底白字后如何实现圆角以及固定状态栏
  • golang的net包
  • vue2脚手架搭建项目流程
  • 3.1 机器学习--线性回归
  • JAVA基础-泛型
  • FineReport 多数据源报表
  • 搞fastjson总是惦记TemplatesImpl谁懂
  • SpingBoot原理
  • 线性表->链表(数据结构)