A Programmer

# C Primer Plus 第六版 第七章课后编程练习答案

``````#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>

// practice 1
void p7_1(void)
{
char ch = 0;
int n_space = 0;
int n_break = 0;
int n_other = 0;

printf("Please enter text to be analyzed(# to terminate):");
while ((ch = getchar()) != '#')
{
if (' ' == ch)
{
n_space++;
}
else if ('\n' == ch)
{
n_break++;
}
else
{
n_other++;
}
}

printf("break = %d, space = %d, other = %d\n", n_break, n_space, n_other);
return;
}

// practice 2
void p7_2(void)
{
char ch = 0;
int i = 0;

printf("Please enter text to be analyzed:(# to terminate):");
while ((ch = getchar()) != '#')
{
if ((i % 8 == 0) && (i != 0))
{
putchar('\n');
}
i++;
printf("%c:%d ", ch, ch);
}

return;
}

// practice 3
void p7_3(void)
{
int n_odd = 0;
int n_even = 0;
int sum_odd = 0;
int sum_even = 0;
int input = 0;

printf("Please enter integer to be analyzed(0 to terminate):");
while (scanf_s("%d", &input))
{
if (0 == input)
{
break;
}
else if (0 == (input % 2))
{
n_even++;
sum_even += input;
}
else
{
n_odd++;
sum_odd += input;
}
}

printf("the average value of %d even is: %f; the average value of %d odd is: %f\n", n_even, (float)(sum_even/n_even), n_odd, (float)(sum_odd/n_odd));

return;

}

// practice 4
void p7_4(void)
{
char ch = 0;

printf("Please enter text to be analyzed:(# to terminate):");
while ((ch = getchar()) != '#')
{
if ('.' == ch)
{
putchar('!');
}
else if ('!' == ch)
{
putchar('!');
putchar('!');
}
else
{
putchar(ch);
}
}

return;
}

// practice 5
void p7_5(void)
{
char ch = 0;

printf("Please enter text to be analyzed (# to terminate):");
while ((ch = getchar()) != '#')
{
switch (ch)
{
case '.':
putchar('!');
break;

case '!':
putchar('!');
putchar('!');
break;

default:
putchar(ch);
break;
}
}

return;
}

// practice 6
void p7_6(void)
{
char ch = 0;
char ch_pre = 0;
int n_appear = 0;

printf("Please enter text to be analyzed (# to terminate): ");
while ((ch = getchar()) != '#')
{
if ('i' == ch)
{
if ('e' == ch_pre)
{
n_appear++;
}
}
ch_pre = ch;
}

printf("ei has appeared %d times.\n", n_appear);
return;
}

// practice 7
#define RATE1 0.15
#define RATE2 0.2
#define RATE3 0.25
void p7_7(void)
{
double work_hours = 0;
double total_income = 0;
double tax = 0;
double  net_income = 0;

printf("How long have you worked:");
scanf_s("%lf", &work_hours);
if (work_hours > 40)
{
work_hours = (work_hours - 40) * 1.5 + 40;
}

total_income = work_hours * 1000;
if (total_income <= 300)
{
tax = total_income * RATE1;
net_income = total_income - tax;
}
else if (total_income <= 450)
{
tax = 300 * RATE1 + (total_income - 300) * RATE2;
net_income = total_income - tax;
}
else
{
tax = 300 * RATE1 + 150 * RATE2 + (total_income - 450) * RATE3;
net_income = total_income - tax;
}

printf("total income = %lf, tax = %lf, net income = %lf\n", total_income, tax, net_income);

return;

}

// practice 8
void p7_8(void)
{
int chooice = 0;

double work_hours = 0;
double total_income = 0;
double tax = 0;
double net_income = 0;
double hourly_wage = 0;

while (1)
{
printf("Enter the number corresponding to the desired pay rate to action:\n");
printf("%-20s%-20s\n%-20s%-20s\n%-20s\n", "1) \$8.75/hr", "2) \$9.33/hr", "3) \$10.00/hr", "4) \$11.20/hr", "5) quit");
scanf_s("%d", &chooice);

switch (chooice)
{
case 1:
hourly_wage = 8.75;
break;

case 2:
hourly_wage = 9.33;
break;

case 3:
hourly_wage = 10.00;
break;

case 4:
hourly_wage = 11.20;
break;

case 5:
return;

default:
printf("Please enter the choice between 1 to 5\n");
continue;
}

printf("How long have you worked:");
scanf_s("%lf", &work_hours);
if (work_hours > 40)
{
work_hours = (work_hours - 40) * 1.5 + 40;
}

total_income = work_hours * hourly_wage;
if (total_income <= 300)
{
tax = total_income * RATE1;
net_income = total_income - tax;
}
else if (300 < total_income && total_income  <= 450)
{
tax = 300 * RATE1 + (total_income - 300) * RATE2;
net_income = total_income - tax;
}
else
{
tax = 300 * RATE1 + 150 * RATE2 + (total_income - 450) * RATE3;
net_income = total_income - tax;
}

printf("total income = %.2lf, tax = %.2lf, net income = %.2lf\n", total_income, tax, net_income);
}

return;
}

// practice 9
void p7_9(void)
{
int input = 0;

scanf_s("%d", &input);

int i = 0;
int j = 0;

for (i = 2; i <= input; i++)
{
for (j = 2; j < sqrt((double)i); j++)
{
if (i % j == 0)
{
break;
}
}
if (j > sqrt(i))
{
printf("%d ", i);
}
}
}

// practice 10
void p7_10(void)
{
int choice = 0;
double income = 0;
double threshold = 0;
double tax = 0;

while (1)
{
printf("1) Single\n2) Head of household\n3) Married,Shared\n4) Married,dieorced\nEnter you choice:");
scanf_s("%d", &choice);
switch (choice)
{
case 1:
threshold = 17850.0;
break;

case 2:
threshold = 23900.0;
break;

case 3:
threshold = 29750.0;
break;

case 4:
threshold = 14875.0;
break;

default:
printf("invalid choice!");
continue;
}

scanf_s("%lf", &income);
if (income < threshold)
{
tax = income * 0.15;
}
else
{
tax = threshold * 0.15 + (income - threshold) * 0.28;
}

printf("category:%d, income:%.2lf, tax:%.2lf\n", choice, income, tax);
}

return;
}

// practice 11
void p7_11(void)
{
double n_artichoke = 0.0;
double n_beet = 0.0;
double n_carrot = 0.0;
double freight = 0.0;
double n_pound = 0.0;
char choice = 0;
double total_cost = 0.0;
double discount = 0.0;
double total_weight = 0.0;

while ('q' != choice)
{
printf("%-20s%-20s\n%-20s%-20s\n", "a) Artichoke", "b) Beet", "c) Carrot", "q) Quit");
printf("Now enter you choose:");
choice = getchar();

switch (choice)
{
case 'a':
printf("How many pounds of Artichoke do you want to buy:");
scanf_s("%lf", &n_pound);
n_artichoke += n_pound;
break;

case 'b':
printf("How many pounds of Beet do you want to buy:");
scanf_s("%lf", &n_pound);
n_beet += n_pound;
break;

case 'c':
printf("How many pounds of Carrot do you want to buy:");
scanf_s("%lf", &n_pound);
n_carrot += n_pound;
break;

case 'q':
continue;

default:
break;
}
while (getchar() != '\n');
}

printf("%-20s%-20s%-20s%-20s\n", "Category", "Price", "Pounds", "Total price");
printf("%-20s%-20s%-20.2lf%-20.2lf\n", "Artichoke", "\$2.05/pound", n_artichoke, (n_artichoke * 2.05));
printf("%-20s%-20s%-20.2lf%-20.2lf\n", "Beet", "\$1.15/pound", n_beet, (n_beet * 1.15));
printf("%-20s%-20s%-20.2lf%-20.2lf\n", "Carrot", "\$1.09/pound", n_carrot, (n_carrot * 1.09));

total_cost = n_artichoke * 2.05 + n_beet * 1.15 + n_carrot * 1.09;
printf("Total_cost:%.2lf", total_cost);
if (total_cost > 100)
{
discount = total_cost * 0.05;
printf(" Discount:%,2lf", discount);
total_cost -= discount;
}

total_weight = n_artichoke + n_beet + n_carrot;
if (0 < total_weight && total_weight <= 5.0)
{
freight = 6.5;
}
else if (5.0 < total_weight && total_weight <= 20)
{
freight = 14.0;
}
else if (20 < total_weight )
{
freight = 14 + (total_weight - 20) * 0.5;
}
printf(" Total_freight:%.2lf", freight);

printf(" Final cost:%.2lf", (total_cost  + freight));

return;
}

int main(int argc, char **argv)
{
p7_11();

while (getchar())  //防止控制台一闪而过
{

}

return 0;
}
``````

1. Ninw说道：

第七章
第七题
else if (300 < total_income <= 450) // 可以这样写吗？
{
tax = 300 * RATE1 + (total_income - 300) * RATE2;
net_income = total_income - tax;
}

1. jimmychen说道：

0.0 谢谢告知，居然写出一个bug了。这样写是不行的，刚刚改回来了

2. Ninw说道：

第七章第八题
continue 好像不能使用在 switch 下。
default:
printf("Please enter the choice between 1 to 5\n");
continue;// 这里？

1. jimmychen说道：

第八题的程序上面有while(1)循环，所以在这个switch case里面可以用continue来跳过while剩余的代码，如果上面没有while循环，switch里面就不能用continue

1. Ninw说道：

哦，明白了。

3. Ninw说道：

第七章第八题
while(1)
{
}
选择正确的输入1到4，一直让循环选择。

4. Ninw说道：

你好，能不能推荐一下学C语言的书籍或资料之类的？ （网上的说什么的都有，不知道听谁的。）

1. jimmychen说道：

我以前也做过网上收集的一些练习题，然后就是自己编写代码实现Linux的命令行程序，例如ls、cp之类的程序

5. Ninw说道：

第七章
最后一题
如果直接选择退出。
结果freight 会显示结果6.5，不应该都是 0 吗？

total_weight = n_artichoke + n_beet + n_carrot;
if (total_weight <= 5.0)
{
freight = 6.5;
}
else if (5.0 < total_weight <= 20) //这里为什么这样写，编译器可以通过啊？
{
freight = 14.0;
}
else
{
freight = 14 + (total_weight - 20) * 0.5;
}
printf(" Total_freight:%.2lf", freight); //这里。

printf(" Final cost:%.2lf", (total_cost - discount + freight));

return;

1. jimmychen说道：

0.0 确实，这道题写出了好多bug
1. total_weight需要添加大于0的条件判断，否则直接退出的话，判断total_weight <= 5.0 为true了 2. else if (5.0 < total_weight <= 20) //这里为什么这样写，编译器可以通过啊？ 这样是可以编译通过的，只是失去了原来的想表达的意思了， 3. 添加了大于零的判断，最后一个就不能直接用else了，否则total_weight会走最后一个else

1. 柴犬说道：

不好意思，我是初学者
请问为什么要加一个 while((getchar()) != '\n') ;
加了有什么作用呢？

2. 友人A说道：

我在第一个if（weight <= 5)里面嵌套一个if else， 判断重量<=0的时候，运费是0 ；else，运费是6.5。这样改可以不？运行了一下的确是输出运费是0。

6. Ninw说道：

total_weight = n_artichoke + n_beet + n_carrot;
if (total_weight <= 5.0) // 这里应该在添加一个大于零的条件。
{
freight = 6.5;
}
else if (5.0 < total_weight <= 20)
{
freight = 14.0;
}
else /*上面如果添加大于零的条件，freight会变成14，这里后面再加个大于20的条件
我的提示出错*/
{
freight = 14 + (total_weight - 20) * 0.5;
}
else
{
//上面的改成else if。 我在这里有加了一个else 才行，允许这样写吗？
}
printf(" Total_freight:%.2lf", freight);

printf(" Final cost:%.2lf", (total_cost - discount + freight));

return;

7. sunrise说道：

第七章 第二题，我想要这样输入行不行:(abc和abc之间输入了一个回车键，用户输入了7个字符[2组abc加一个回车键，共7个])。然后一次性在一行打印7对 字符和ASCII码
abc
abc

1. sunrise说道：

第三题，平均数用printf（“%f”）是不是好些，假如输入的是3、7、1，11/3这不就是浮点数了么（
不知道理解的对不，我刚学习程序）

1. jimmychen说道：

是的，改成浮点数会好一些

2. jimmychen说道：

这个回车键用printf来打印都会换行的，除非用转义表示换行符；如果想等到全部输入完成后再一次性打印字符和ascii码的话可以使用数组来保存输入的字符，等输入了#号后再输出数组的内容

8. sunrise说道：

第八题：整个程序都在while（1）
{
}
这个循环中；while中含有switch break，假如当我选中1的时候，按照书本上讲的，应该就跳出while循环了，程序就应该结束了，但是我运行版主的程序，事实上并非如此，还可以一直运行下去。难道
switch (choice)
{
}这个也能算一个循环，break跳出了这个switch循环，还在while循环里面，但是我看书上的例子都是直接跳出while的，劳烦吧主解答下

1. jimmychen说道：

switch不是循环，第八题，按照打印的提示，选5才是退出while循环的

9. ch说道：

楼主，第8题如果输入不是数字的话就会一直循环显示界面，只有1～5以外的数字才能重新显示界面提示输入。我用你的代码测试也是，是我编译器的问题吗？

1. jimmychen说道：

写的程序都只是做简单的功能实现，类似输入错误判断之类的都没有做

10. zch666666说道：

第三题求平均数时，直接用%f显示(odd_sum/n_odd)结果我的编译结果显示为0.00000，我在表达式前面加了强制类型转换为float结果就正确了
printf(“奇数有%d个，奇数的平均值为%5.2f\n”,n_odd,(float)(odd_sum/n_odd));
我是初学者，不知道这样做好不好

1. jimmychen说道：

你这个很好啊，不加float强制转换的话整除会被截断成整型输出的

11. Helloworld!说道：

不好意思请教一下 实在没看懂
第七章第六题
if ('i' == ch)
{
if ('e' == ch_pre)
{
n_appear++;
}
}
这个地方是先检查‘i’然后再检查前一个字符‘e’ 如果为真n_appear++;对吧
我看了很久 实在不知道怎么做到检查前一个字符的 是_pre有什么特别作用么？
如果_pre的作用是检查前一个字符 那么如何检查后一个字符呢？
感谢楼主回答！

1. jimmychen说道：

这里只需要记录前一个字符就好了吧，你截取的代码下面有一行'ch_pre = ch;'，就是用来记录前一个字符的

12. 柴犬说道：

求问第七章第六题为什么
if( c =='i')
{if(prev =='e')
n++;}

if(prev == 'e' && c =='i')
n++;
所得的结果不一样

1. jimmychen说道：

额，应该是一样的吧

13. 清111说道：

楼主打扰啦，第六题这样做好像也行，不知道有没有什么问题，（初学者）
#include
int main(void)
{
char ch;
int n=0;
printf("Please enter text to be analyzed (# to terminate):");
while((ch=getchar())!='#')
{
if(ch=='e')
continue;
else if(ch=='i')
n++;
else
continue;
}

printf("\n");
printf("there are %d 'ei'\n",n);
return 0;
}

1. jimmychen说道：

这样做有问题吧，要是我输入10个i，你这最后不就打印有10个ei了么？

14. 张小亮说道：

第七题 scanf_s("%lf", &work_hours);
if (work_hours > 40)
{
work_hours = (work_hours - 40) * 1.5 + 40;
}

total_income = work_hours * 1000;
if (total_income <= 300)
{
tax = total_income * RATE1;
net_income = total_income - tax;
}
total_income ×1000是总工资 不成立 怎么理解这个

1. jimmychen说道：

抱歉，不是特别理解你想表达的意思呢？

15. aiguo说道：

我看到第八章的习题七的时候，重新看了下第七章的第八题（这两题有联系），因为第八章主要讲了很多处理换行符的问题，现在看第七题的时候发现，scanf_s("%d", &chooice)输入产生的换行符为什么不影响scanf_s("%lf", &work_hours)这个读取，按照我现在的理解，第一个scanf 产生的换行符，会留在队列里面，被这个scanf_s("%lf", &work_hours)读取到，但是work_hours是double类型，所以一直没法读取，程序就会一直卡主。但是事实上 这个程序可以正常运行。这是什么原因？

1. aiguo说道：

这个问题是针对第八题的

16. 热心网友说道：

第十题如果输入了字母的话就会导致无限循环，下一章其实讲了解决方法，用scanf("%*s);跳过非数字字符。

17. snail说道：

第2题是不是并没有对一行打印8个字符这一要求进行处理，只是实现了字符转ASCII码这一要

1. jimmychen说道：

i % 8这一行就是处理这种情况的

18. 不吃鱼的汤姆猫说道：
19. 我把名字吃了说道：

博主，我有个第十一题的疑问：
while ('q' != choice)
{......}里面的 while (getchar() != '\n');具有什么作用？

1. jimmychen说道：

清除多余的回车键用的

20. 嘻嘻说道：

谢谢大佬的答案分享。其中2第二题有一个小bug，那就是只要一输入字符，打印出来，最终行都会打印出
10： ，而且一按回车就打印10：不美观。如果在i++的下一行加上if (ch!='\n')进行判断就不会出现这个问题。