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);
}  

运行结果:
在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值