C Primer Plus 第六版编程练习第七章答案和记录一些学习历程
感觉写博客的话,自己会把书看的更认真些- 。- ,因为也不是计算机科班出身,把自己学习计算机科学的一些历程记录在这个博客里,如博文有问题处,请不吝指教,不胜感激。
1,编写一个程序读取输入,读到#字符停止,然后报告读取空格数,换行符数目以及所有的其它字符数目。
首先:读到#字符使程序停止,我使用这一章学到的getchar()语句,与第五章使用scanf("%lf", &hwen)== 1 语句,读到q或其他不是数字的值使程序停止。
这两种情况区别在于
第一种只在char类型中的#输入请况下使程序停止。——运用情况:同种类型单个字符。
第二种是当程序读取到不是浮点型的数值时程序停止(任意字符都可以)——运用情况:利用两种不同类型输入的区别。
其次:分别用三个变量充当计数器。因此需要一共需要声明4个变量。
/* Programming Exercise 7-1*/ #include <stdio.h> int main() { char ch; int sp_ct = 0; int nl_ct = 0; int other = 0; printf("please enter the characters: \n");//输入字符 while ((ch = getchar()) != '#') { if (ch == ' ') sp_ct++;//计数空格字符 else if (ch == '\n') nl_ct++;//计数换行字符 else other++;//计数其他字符 } printf("spaces: %d, newlines'\\n': %d, others: %d\n", sp_ct, nl_ct, other); return 0; }
运行结果:
2,编写一个程序读取输入,读到#字符停止。程序要打印每个输入的字符以及对应的ASCII码(十进制)。一行打印8个字符。建议:使用字符计数和求模运算符(%)在每8个循环周期时打印一个换行符。
首先:输入——读到#字符停止实现方式如题1,
其次:输出——使用转换说明符转换数据类型;
最后:每8个字符换行一次,使用字符计数和求模运算符(%)在每8个循环周期时打印一个换行符。
/* Programming Exercise 7-2*/ #include <stdio.h> #define SIZE 8 int main(void) { char ch; int count = 0; printf("please enter the characters:"); while ((ch = getchar()) != '#')//输入#字符停止输入 { if (ch == '\n')//一个防错模块:输入回车键enter时程序停止。可以不要。 { printf("\\n-%d\t",ch); break; } else printf("%c-%d\t",ch,ch);//制表符使输出整齐排列 count++; while (count % SIZE == 0)// 每8个字符换一次行 printf("\n"); } return 0; }
运行结果:
3.编写一个程序,读取整数,直到用户输入0。输入结束后,程序应该报告输入的偶数(不包括0)个数、这些偶数的平均值,输入的奇数个数以及奇数的平均值。
这道题很简单啊。
首先:用累加可以求出总和。
再用:计数器记录数据个数,平均值等于总和除以个数。(需要注意的就是当个数为0的时候,没有平均数,可以输出平均数为零,也可以不输出显示平均数语句。这里我采用的后者)
最后:1个输入,4个输出。一共需要声明5个变量。
/* Programming Exercise 7-3*/ #include <stdio.h> int main(void) { int n; double sumeven = 0.0; int ct_even = 0; double sumodd = 0.0; int ct_odd = 0; printf("please enter a number:"); while (scanf("%d", &n) == 1 && n != 0)//当输入非整数或0时结束程序 { if (n % 2 == 0) { sumeven += n;//偶数的总和 ct_even++;//偶数的个数 } else { sumodd += n;//奇数的总和 ct_odd++;//奇数的个数 } printf("please enter the next number(0 to quit):"); } printf("\nNumber of evens: %d\n", ct_even);//当偶数个数为0时,不求平均数,只输出偶数个数为0 if (ct_even > 0) printf("average: %g\n", sumeven / ct_even); printf("Number of odds: %d\n", ct_odd);//当奇数个数为0时,不求平均数,只输出奇数个数为0 if (ct_odd > 0) printf("average: %g\n", sumodd / ct_odd); printf("done!\n"); return 0; }
运行结果:
4.使用if else语句编写一个程序读取输入,读到#停止。用感叹号代替句号,用两个感叹号代替原来的感叹号,最后报告进行了多少次替代。
这个就更简单了,
输入:用一个变量记录输入
输出:用一个计数器记录需要进行多少次替代。(分开记录替代次数就两个变量)
一共需要声明两个变量。
/* Programming Exercise 7-4*/ #include <stdio.h> int main(void) { char ch; int count = 0; printf("please enter the characters:"); while((ch = getchar()) != '#') { if(ch == '.')//输入句号,计数器+1 { putchar('!'); count++; } else if(ch == '!')//输入感叹号,计数器+1 { putchar('!'); putchar('!'); count++; } else { putchar(ch); } } printf("\nexchanged %d times\n", count); return 0; }
运行结果:
5.用switch重写练习4。
/* Programming Exercise 7-5*/ #include <stdio.h> int main(void) { char ch; int ct1 = 0; int ct2 = 0; printf("please enter a charaters(# to quit):"); while ((ch = getchar()) != '#') { switch(ch)//根据ch选择case { case '.' : putchar('!'); ct1++; break; case '!' : putchar('!'); putchar('!'); ct2++; break; default://其他情况直接输出字符 putchar(ch); } } printf("\n%d replacement(s) of . with !\n", ct1); printf("%d replacement(s) of ! with !!\n", ct2); return 0; }
运行结果:
6.编写程序读取输入,读到#停止,报告ei出现的次数。
首先:关键在于记录前一个字符的同时也要记录后一个字符,也就是说ei是紧密连接在一起的,中间不能有其他字符。才能计数一个。所以应该使用多重嵌套(三重嵌套太复杂)或用变量表示两者关系。
那么这样:我们使用e=1表示前面读取了一个e,当第二次输入时如果是i,则计数,如果不是i,就不计数,并把e重置为e=0。
/* Programming Exercise 7-6*/ #include <stdio.h> int main(void) { char ch; int e=0; int count=0; printf("please enter the characters(# to quit):"); while((ch = getchar()) != '#' ) { if( ch=='e' ) e=1;//前一个字符读得e else { if( ch=='i' && e==1 ) count++;//后一个字符读的i e=0;//无论后一个字符是否读到i都将其重置。 } } printf( "\nei appeared %d times.\n", count); return 0; }
运行结果:
7.编写一个程序,提示用户输入一周工作的小时数,然后打印工资总额、税金和净收入。做如下假设:a.基本工资 = 10美元/小时b.加班(超过40小时) = 1.5倍的时间 c.税率: 前300美元为15% 续150美元为20% 余下的为25%。用#define定义符号常量。不用在意是否符合当前的税法。
这道题很简单,把表达式写对就可以了。
输入:一个变量。
输出:四个变量记录。
实现方式:八个明示常量。使用else if配对的方式做选择比较方便。
// Programming Exercise 7-7// #include <stdio.h> #define BASEPAY 10 #define BASEHRS 40 #define OVERTIME 1.5 #define AMT1 300 #define AMT2 150 #define RATE1 0.15 #define RATE2 0.20 #define RATE3 0.25 int main(void) { double hours; double gross; double net; double taxes; printf("Enter the number of hours worked this week: "); scanf("%lf", &hours); if (hours <= BASEHRS) gross = hours * BASEPAY; else gross = BASEHRS * BASEPAY + (hours - BASEHRS) * BASEPAY * OVERTIME; if (gross <= AMT1) taxes = gross * RATE1; else if (gross <= AMT1 + AMT2) taxes = AMT1 * RATE1 + (gross - AMT1) * RATE2; else taxes = AMT1 * RATE1 + AMT2 * RATE2 + (gross - AMT1 - AMT2) * RATE3; net = gross - taxes; printf("gross: $%.2f; taxes: $%.2f; net: $%.2f\n", gross, taxes, net); return 0; }
运行结果:
8.修改练习7的假设a,让程序可以给出一个供选择的工资等级菜单。使用switch完成工资等级选择。运行程序后,显示的菜单应该类似这样: Enter the number corresponding to the desired pay rate or action:1) $8.75/hr 2) $9.33/hr 3)$10.00/hr 4) $11.20/hr 5) quit 如果选择 1~4 其中的一个数字,程序应该询问用户工作的小时数。程序要通过循环运行,除非用户输入 5。如果输入 1~5 以外的数字,程序应提醒用户输入正确的选项,然后再重复显示菜单提示用户输入。使用#define创建符号常量表示各工资等级和税率。
这道题还是有点复杂啊,成功运行花了一个小时。。。
首先:重复显示菜单,为了方便起见,我们先把这个显示菜单做成一个函数,然后调用它。
其次:程序需要循环运行,直到输入5结束,说明我们在用户输入1,2,3,4,5(程序停止是它的子层)和其他输入(提示输入正确的选项,这是它的子层)(这几个选项是一层)的时候,外层还要有一个大循环,用于不断循环运行计算工资程序。所以这个程序大体需要三层嵌套。
最后:观察这几个输入最外层的共性,于是采用scanf成功读入作为外层判断依据。
// Programming Exercise 7-8// #include <stdio.h> #define BASEPAY1 8.75 #define BASEPAY2 9.33 #define BASEPAY3 10.00 #define BASEPAY4 11.20 #define BASEHRS 40 #define OVERTIME 1.5 #define AMT1 300 #define AMT2 150 #define RATE1 0.15 #define RATE2 0.20 #define RATE3 0.25 #define LONG 65 void copy(char n, int m);//声明打印*号函数 void head(void);//声明选择菜单函数 int main(void) { double hours; double gross; double net; double taxes; double basepay;//基本工资 int num;//选择选项 head();//调用选择菜单函数 while(scanf("%d", &num) != 0)//循环读取用户输入选择 { switch(num)//选择基本工资 { case 1: basepay = BASEPAY1; break; case 2: basepay = BASEPAY2; break; case 3: basepay = BASEPAY3; break; case 4: basepay = BASEPAY4; break; } if (num > 0 && num < 5)//对1,2,3,4这四个选项进行计算 { printf("Enter the number of hours worked this week: "); scanf("%lf", &hours); if (hours <= BASEHRS) gross = hours * basepay; else gross = BASEHRS * basepay + (hours - BASEHRS) * basepay * OVERTIME; if (gross <= AMT1) taxes = gross * RATE1; else if (gross <= AMT1 + AMT2) taxes = AMT1 * RATE1 + (gross - AMT1) * RATE2; else taxes = AMT1 * RATE1 + AMT2 * RATE2 + (gross - AMT1 - AMT2) * RATE3; net = gross - taxes; printf("gross: $%.2f; taxes: $%.2f; net: $%.2f\n\n", gross, taxes, net); head();//未输入5之前循环调用选择菜单函数 } else if(num == 5)//输入5跳出循环 break; else { printf("incorrect input,please re-enter!\n");//提示输入错误 head();//再次调用选择菜单函数 } } return 0; } void copy(char n, int m)//定义打印*号函数 { int count; for(count = 0; count < m; count++) putchar(n); printf("\n"); } void head(void)//定义选择菜单函数 { copy('*', LONG); printf("Enter the number corresponding to the desired pay rate or action: \n"); printf("1) $8.75/hr 2) $9.33/hr\n3) $10.00/hr 4) $11.20/hr\n5) quit \n"); copy('*', LONG); }
运行结果:
9.编写一个程序,只接受正整数输入,然后显示所有小于或等于该数的素数。
又到到了喜闻乐见的找素数环节:本来想了一下,用2到他本身的数除一遍这个数就可以了。但是又仔细的想了一下,万一这个数很大很大,从2到本身除下去,那的花多久时间啊。后来一百度:我发现还有什么费马小定理,lucas序列,椭圆曲线算法的解法。。。看来这个东西远不止我想的那么简单啊哈哈哈哈。
首先:第一个难点应该在于如何限定输入正整数,scanf语句无法限定输入,所以我们先定义输入为整型,然后用scanf读取输入,判断是否成功读取且读取的数大于0,即可达成我们的目的。(好像浮点型会被强制转换为整型,暂时还没想到什么好办法限定浮点型不能输入)
其次:如何判断一个数是不是素数,大体意思是从2除到他本身,但是因为因为如果一个数不是素数,那么它一定可以由两个自然数相乘得到,其中一个大于或等于它的平方根,一个小于或等于它的平方根,并且成对出现。
所以:我们对这个办法进行优化;我们对这个数从2除到他的平方根(如果他不是素数,那么必有一个可以整除他的除数小于他的平方根)。这样可以节约一半时间。C中要调用math.h头文件可以有开方函数,我们不哟个开方函数,对分母平方也可以达到相同目的。
注:
还有一种筛法:我们已知2是最小素数,于是从2开始筛选(定义筛选的基数为n,此时n = 2)。那么所有的2的倍数都不是素数,因为至少可以被2整除。之后对3、4、5、6…进行筛选(此时n = 3、4、5、6、7…)这个叫做厄拉多塞筛法。有空写一下这个程序。。。
// Programming Exercise 7-8// #include <stdio.h> int main(void) { int limit; int num; int div; int numIsPrime;//判断数字是否为素数 printf("Enter a positive integer: "); if (scanf("%d", &limit) != 0 && limit > 0)//判断输入是否为正整数 { if (limit == 1)//输入为1时的特殊情况 printf("No primes.\n"); else printf("Here are the prime numbers up through %d\n", limit);//小于等于该输入数字的素数 for (num = 2; num <= limit; num++)//遍历所有小于等于该数字的数字 { for (div = 2, numIsPrime = 1; (div * div) <= num; div++)//判断这些数字是否是素数 if (num % div == 0)//不是素数 numIsPrime = 0; if (numIsPrime == 1)//是素数 printf("%d is prime.\n", num); } } else//如果输入其他字符,则提示无法读取 printf("This program can't read your input!\n"); return 0; }
运行结果:
10.1988年的美国联邦税收计划是近代最简单的税收方案。它分为4个类别,每个类别有两个等级。 下面是该税收计划的摘要(美元数为应征税的收入):例如,一位工资为20000美元的单身纳税人,应缴纳税0.15×17850+0.28×(20000−17850)美元。编写一个程序,让用户指定缴纳税金的种类和应纳税收入,然后计算税金。程序应通过循环让用户可以多次输入。
这道题和第8题思路差不多。比第8题还要简单些,只有一个输出。
// Programming Exercise 7-10// #include <stdio.h> #define BASEPAY1 17850.00 #define BASEPAY2 23900.00 #define BASEPAY3 29750.00 #define BASEPAY4 14875.00 #define RATE1 0.15 #define RATE2 0.28 #define LONG 44 void copy(char n, int m);//声明打印*号函数 void head(void);//声明选择菜单函数 int main(void) { double basepay; double income; double taxes; int type; head();//调用菜单 while(scanf("%d", &type) != 0) { switch(type) { case 1: basepay = BASEPAY1; break; case 2: basepay = BASEPAY2; break; case 3: basepay = BASEPAY3; break; case 4: basepay = BASEPAY4; break; } if (type > 0 && type < 5) { printf("Enter the gross of your income: \n"); scanf("%lf", &income); if (income <= basepay) taxes = income * RATE1; else taxes = (income - basepay) * RATE2 + basepay* RATE1; printf("income: $%.2f; taxes: $%.2f\n\n", income, taxes); head();//未输入5之前循环调用选择菜单函数 } else if(type == 5) break; else { printf("incorrect input,please re-enter!\n"); head();//调用菜单 } } return 0; } void copy(char n, int m)//生成*函数定义 { int count; for(count = 0; count < m; count++) putchar(n); printf("\n"); } void head(void)//选择菜单函数定义 { copy('*', LONG); printf("Please enter what's the type of tax payment?\n"); printf("1) 单身 2) 户主\n3) 已婚,共有 4) 已婚离异\n5) 退出程序 \n"); copy('*', LONG); }
运行结果:
11.ABC 邮购杂货店出售的洋蓟售价为 2.05 美元/磅,甜菜售价为 1.15 美元/磅,胡萝卜售价为 1.09美元/磅。在添加运费之前,100美元的订单有5%的打折优惠。少于或等于5磅的订单收取6.5美元的运费和包装费,5磅~20磅的订单收取14美元的运费和包装费,超过20磅的订单在14美元的基础上每续重1磅增加0.5美元。 编写一个程序,在循环中用switch语句实现用户输入不同的字母时有不同的响应,即输入a的响应是让用户输入洋蓟的磅数,b是甜菜的磅数,c是胡萝卜的磅数,q 是退出订购。程序要记录累计的重量。即,如果用户输入 4 磅的甜菜,然后输入 5磅的甜菜,程序应报告9磅的甜菜。然后,该程序要计算货物总价、折扣(如果有的话)、运费和包装费。随后,程序应显示所有的购买信息:物品售价、订购的重量(单位:磅)、订购的蔬菜费用、订单的总费用、折扣(如果有的话)、运费和包装费,以及所有的费用总额。
这个题目难倒是不难,就是要计算的太多了。。。
首先:我们理一下,第一个模块应该是订购模块,主要统计各蔬菜重量。如之前8和10题的选择菜单一样,要注意的就是因为是字符输入,window系统enter键既是回车也是换行。所以要将缓冲区的换行符清空。其他基本一样。
其次:再根据重量确定运费,订购蔬菜费。用else if联合语句。
最后:计算一下总花费,折扣。
/* Programming Exercise 7-11 */ #include <stdio.h> #include <ctype.h> #define LONG 34 void copy(char n, int m);//声明打印*号函数 void head(void);//声明选择菜单函数 int main(void) { const double price_artichokes = 2.05; const double price_beets = 1.15; const double price_carrots = 1.09; const double DISCOUNT_RATE = 0.05; const double under5 = 6.50; const double under20 = 14.00; const double base20 = 14.00; const double extralb = 0.50; char ch; double lb_artichokes = 0; double lb_beets = 0; double lb_carrots = 0; double lb_temp; double lb_total; double cost_artichokes; double cost_beets; double cost_carrots; double cost_total; double final_total; double discount; double shipping; head();//调用菜单 while ((ch = getchar()) != 'q' && ch != 'Q') //输出q或Q退出订购 { if (ch == '\n') continue; while (getchar() != '\n') continue; ch = tolower(ch);//调用大写字母转换小写字母函数,兼容大小写。 switch (ch)//记录累计重量。 { case 'a' : printf("Enter pounds of artichokes: "); scanf("%lf", &lb_temp); lb_artichokes += lb_temp; break; case 'b' : printf("Enter pounds of beets: "); scanf("%lf", &lb_temp); lb_beets += lb_temp; break; case 'c' : printf("Enter pounds of carrots: "); scanf("%lf", &lb_temp); lb_carrots += lb_temp; break; default : printf("%c is not a valid choice.\n", ch); } head(); //再次调用订购菜单 } cost_artichokes = price_artichokes * lb_artichokes; cost_beets = price_beets * lb_beets; cost_carrots = price_carrots * lb_carrots; cost_total = cost_artichokes + cost_beets + cost_carrots; //计算订购总花费。 lb_total = lb_artichokes + lb_beets + lb_carrots;//计算订购总重量 if (lb_total <= 0)//总重为0磅时的运费 shipping = 0.0; else if (lb_total < 5.0)//总重为0到5磅时的运费 shipping = under5; else if (lb_total < 20)//总重为5到20磅时的运费 shipping = under20; else //总重超过20磅时的运费 shipping = base20 + extralb * lb_total; if (cost_total > 100.0)//计算折扣 discount = DISCOUNT_RATE * cost_total; else discount = 0.0; final_total = cost_total + shipping - discount; //最终花费 printf("Your order:\n"); printf("%.2f lbs of artichokes at $%.2f per pound:$ %.2f\n", lb_artichokes, price_artichokes, cost_artichokes); printf("%.2f lbs of beets at $%.2f per pound: $%.2f\n", lb_beets, price_beets, cost_beets); printf("%.2f lbs of carrots at $%.2f per pound: $%.2f\n", lb_carrots, price_carrots, cost_carrots); printf("Total cost of vegetables: $%.2f\n", cost_total); if (cost_total > 100) printf("Volume discount: $%.2f\n", discount); printf("Shipping: $%.2f\n", shipping); printf("Total charges: $%.2f\n", final_total); return 0; } void copy(char n, int m)//生成*函数定义 { int count; for(count = 0; count < m; count++) putchar(n); printf("\n"); } void head(void)//选择菜单函数定义 { copy('*', LONG); printf("Please enter to buy what you want.\n"); printf("(a) artichokes (b) beets\n(c) carrots (q) exit \n"); copy('*', LONG); }
运行结果:
- 点赞 1
- 收藏
- 分享
- 文章举报
- C Primer Plus 第六版编程练习第十章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第六章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第四章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第二章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第一章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第十一章答案和记录一些学习历程
- C++ Primer Plus 第六版 学习笔记 第七章 编程练习答案
- C++ primer Plus(第六版)中文版 第二章 开始学习C++ 编程练习答案
- c primer plus 第六版 第七章编程练习答案
- C++ Primer Plus第六版 第七章 编程练习答案
- 【学习C++】C++ Primer Plus (第六版)第七章编程练习6-10
- C++ PRIMER PLUS (第六版) 中文版 第七章编程练习答案
- C ++ Primer Plus 第六版 第七章编程练习答案
- C primer plus 第六版 第七章 编程练习 答案
- C++ primer Plus(第六版)中文版 第七章 函数——C++的编程模块 编程练习答案
- C Primer Plus (第六版)中文版 第七章 编程练习答案
- C++primer plus第六版课后编程练习答案7.9
- C++primer plus第六版课后编程练习答案8.4
- C++primer plus第六版课后编程练习答案9.4
- C++primer plus第六版课后编程练习答案10.3