第七章 C控制语句:分支和跳转


编程练习:


1.编写一个程序。该程序读取输入直到遇到#字符,然后报告读取的空格数目、读取的换行符数目以及读取的所有其他字符数目。

#include <stdio.h>

int main(void)
{
	int a=0, b=0, c=0;
	char ch;
	
	while ((ch = getchar()) != '#')
	{
		if (ch != ' ' && ch != '\n')
			c++;
		else if (ch != ' ')
			b++;
		else
			a++;
	}
	printf("空 格 数 目 :%3d\n", a);
	printf("换 行 数 目 :%3d\n", b);
	printf("其它字符数目:%3d\n", c);

	return 0;
}



2.编写一个程序,该程序读取输入直到遇到#字符。使程序打印每个输入的字符以及它的十进制ASCII码。每行打印8个字符/编码对。建议:利用字符计数和模运算符(%)在每8个循环周期时打印一个换行符。

#include <stdio.h>

int main(void)
{
	int i = 0;
	char ch;
	char str[100];
	
	printf("请输入字符(输入#结束):");
	do 
	{	
		ch = getchar();
		str[i++] = ch;
	} 
	while (ch != '#');

	for (i = 0; str[i] != '#'; i++)
	{
		if (str[i] == '\n')
			printf(" '\\n'/%-3d ", str[i]);
		else if (str[i] == '\t')
			printf(" '\\t'/%-3d ", str[i]);
		else
			printf("  '%c'/%-3d ", str[i], str[i]);
		if (i % 8 == 7)
			putchar('\n');
	}
	putchar('\n');

	return 0;
}



3.编写一个程序。该程序读取整数,直到输入0。输入终止后,程序应该报告输入的偶数(不包括0)总个数、偶数的平均值,输入的奇数总个数以及奇数的平均值。

#include <stdio.h>

int main(void)
{
	int input;
	int even = 0, odd = 0;
	int even_sum = 0, odd_sum = 0;

	printf("请输入整数(输入0结束):");
	while (scanf("%d", &input) == 1 && 0 != input)
	{
		if (input % 2 == 0)
		{
			even++;
			even_sum += input;
		}
		else
		{
			odd++;
			odd_sum += input;
		}
	}
	if (0 == even) 
		printf("偶数的总个数:0 平均值:0\n");
	else
		printf("偶数的总个数:%d 平均值:%d\n", even, even_sum / even);
	if (0 == odd)
		printf("偶数的总个数:0 平均值:0\n");
	else
		printf("奇数的总个数:%d 平均值:%d\n", odd, odd_sum / odd);

	return 0;
}



4.利用if else语句编写程序读取输入,直到#。用一个感叹号代替每个句号,将原有的每个感叹号用两个感叹号代替,最后报告进行了多少次替代。

#include <stdio.h>

int main(void)
{
	char ch;
	int a = 0, b = 0;

	printf("请输入字符串,以“#”结束: \n");
	while ((ch = getchar()) != '#')
	{
		if (ch == '.')
		{
			putchar('!');
			a++;
		}
		else
		{
			if (ch == '!')
			{
				putchar('!');
				putchar('!');
				b++;
			}
			else
			{
				putchar(ch);
			}
		}
	}
	printf("\n");
	printf("'.'有%d次被替代为'!'\n", a);
	printf("'!'有%d次被替代为'!!'\n", b);
	printf("总共替代了%d次\n", a + b);

	return 0;
}



5.用switch重做练习3编写一个程序。该程序读取整数,直到输入0。输入终止后,程序应该报告输入的偶数(不包括0)总个数、偶数的平均值,输入的奇数总个数以及奇数的平均值。

#include <stdio.h>

int main(void)
{
	int input;
	int even = 0, odd = 0;
	int even_sum = 0, odd_sum = 0;

	printf("请输入整数(输入0结束):");
	while (scanf("%d", &input) == 1 && 0 != input)
	{
		switch (input % 2)
		{
		case 0: even++; even_sum += input;
			break;
		case 1: odd++; odd_sum += input;
			break;
		}
	}
	if (0 == even)
		printf("偶数的总个数:0 平均值:0\n");
	else
		printf("偶数的总个数:%d 平均值:%d\n", even, even_sum / even);
	if (0 == odd)
		printf("偶数的总个数:0 平均值:0\n");
	else
		printf("奇数的总个数:%d 平均值:%d\n", odd, odd_sum / odd);

	return 0;
}



6.编写一个程序读取输入,直到#,并报告序列ei出现的次数。此程序必须要记住前一个字符和当前的字符。用诸如“Receive your eieio award.”的输入测试它。

#include <stdio.h>

int main(void)
{
	char ch = '*',temp;
	int i = 0;

	printf("请输入字符,直到#结束:");
	while (temp = ch, ch = getchar(), '#' != ch)	
		if ('e' == temp && 'i' == ch)
			i++;

	printf("ei出现的次数为:%d\n", i);

	return 0;
}



7.编写程序,要求输入一周中的工作小时数,然后打印工资总额、税金以及净工资。作如下假设:

a.基本工资等级=10.00美元/小时

b.加班(超过40小时)=1.5倍的时间

c.税率    前300美元为15%

下一个150美元为20%

余下的为25%

用#define定义常量,不必关心本例是否符合当前的税法。

#include <stdio.h>

#define LIMIT1 300
#define TAX1 0.15
#define LIMIT2 150
#define TAX2 0.2
#define LIMIT3 450
#define TAX3 0.25
#define TIME 40
#define ADD 1.5
#define BASE 10.00

int main(void)
{
	float time;
	float total, tax, salary;

	printf("请输入你一周工作的小时数:");
	scanf("%f", &time);
	if (time > TIME)
		time = (time - TIME) * ADD + TIME;

	total = time * BASE;

	if (total <= LIMIT1)
		tax = total * TAX1;
	else if (total <= LIMIT3)
		tax = LIMIT1 * TAX1 + (total - LIMIT1) * TAX2;
	else
		tax = LIMIT1 * TAX1 + LIMIT2 * TAX2 + (total - LIMIT3) * TAX3;
	salary = total - tax;


	printf("本周总工资:%.2f;税金:%.2f;实际工资:%.2f\n",
		total, tax, salary);

	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) $lO.OO/hr                 4) $11.20/hr

5) quit

如果选择l到4.那么程序应该请求输入工作小时数。程序应该一直循环运行,直到输入5。如果输入l到5以外的选项,那么程序应该提醒用户合适的选项是哪些,然后再循环。用#define为各种工资等级和税率定义常量。

#include <stdio.h>

#define LIMIT1 300
#define TAX1 0.15
#define LIMIT2 150
#define TAX2 0.2
#define LIMIT3 450
#define TAX3 0.25
#define TIME 40
#define ADD 1.5
#define BASE1 8.75
#define BASE2 9.33
#define BASE3 10.00
#define BASE4 11.20

void menu(void);
void fun(float base);

int main(void)
{
	
	char ch;
	
	menu();

	while (( ch = getchar()) != '5')
	{
		while (getchar() != '\n')
			continue;
		switch (ch)
		{
		case '1': fun(BASE1);
			break;
		case '2': fun(BASE2);
			break;
		case '3': fun(BASE3);
			break;
		case '4': fun(BASE4);
			break;
		default: printf("Please enter the correct option(1 2 3 4 or 5):");
		}
		while (getchar() != '\n')
			continue;
		putchar('\n');
		menu();
	}

	return 0;
}

void menu(void)
{
	printf("Enter the number corresponding to");
	printf(" the desired pay rate or action :\n");
	printf("1) $8.75 / hr         2) $9.33 / hr \n");
	printf("3) $lO.OO / hr        4) $11.20 / hr\n");
	printf("5) quit\n");
}

void fun(float base)
{
	float time;
	float total, tax, salary;

	printf("请输入一周工作的时间(小时):");
	scanf("%f", &time);
	if (time > TIME)
		time = (time - TIME) * ADD + TIME;

	total = time * base;

	if (total <= LIMIT1)
		tax = total * TAX1;
	else if (total <= LIMIT3)
		tax = LIMIT1 * TAX1 + (total - LIMIT1) * TAX2;
	else
		tax = LIMIT1 * TAX1 + LIMIT2 * TAX2 + (total - LIMIT3) * TAX3;

	salary = total - tax;


	printf("本周总工资:%.2f;税金:%.2f;实际工资:%.2f\n",
		total, tax, salary);
}



9.编写一个程序,接受一个整数输入,然后显示所有小于或等于该数的素数。

#include <stdio.h>

int main(void)
{
	int a;
	int i, j;

	printf("请输入一个整数:");
	scanf("%d", &a);
	printf("    1是素数\n");
	for (i = 2; i <= a; i++)
	{
		for (j = 2; j*j <= i; j++)
		{
			if (i % j == 0)
				break;
		}
		if (j*j > i)
		{
			printf("%5d是素数\n", i);
		}	
	}

	return 0;
}



10. 1988年United States Federal Tax Schedule是近期最基本的。它分为4类,每类有两个等级。下面是其摘要;美元数为应征税的收入。

┏━━━━━━┳━━━━━━━━━━━━━━━━━━┓

┃ 种  类   ┃    税 金                 ┃

┣━━━━━━╋━━━━━━━━━━━━━━━━━━┫

┃单 身     ┃前17,850美元按15%,超出部分按28%  ┃

┣━━━━━━╋━━━━━━━━━━━━━━━━━━┫

┃户 主     ┃前23,900美元按15%,超出部分按28%  ┃

┣━━━━━━╋━━━━━━━━━━━━━━━━━━┫

┃已婚 共有  ┃前29,750美元按15%,超出部分按28%  ┃

┣━━━━━━╋━━━━━━━━━━━━━━━━━━┫

┃已婚 离异  ┃前14,875美元按l5%,超出部分按28%  ┃

┗━━━━━━┻━━━━━━━━━━━━━━━━━━┛

例如,有20 000美元应征税收入的单身雇佣劳动者应缴税金0.15×17 850美元+0.28×(20 000美元-17 850美元)。

编写一个程序,让用户指定税金种类和应征税收入,然后计算税金。使用循环以便用户可以多次输入。

#include <stdio.h>
#define TAXD 0.15
#define TAXU 0.28
#define KIND1 17850.00
#define KIND2 23900.00
#define KIND3 29750.00
#define KIND4 14875.00

void menu(void);
void fun(double);

int main(void)
{
	char ch;
	menu();

	while ((ch = getchar()) != '5')
	{
		while (getchar() != '\n')
			continue;
		switch (ch)
		{
		case '1': fun(KIND1);
			break;
		case '2': fun(KIND2);
			break;
		case '3': fun(KIND3);
			break;
		case '4': fun(KIND4);
			break;
		default: printf("请输入正确的选项(1 2 3 4 or 5):");
		}
		putchar('\n');
		menu();
		while (getchar() != '\n')
			continue;
	}
	return 0;
}

void menu(void)
{
	printf("请选择付税类别:\n");
	printf("1)单身。			2)户主。\n");
	printf("3)已婚,共有。		4)已婚,离异。\n");
	printf("5)退出。\n");
}

void fun(double kind)
{
	double income;
	double tax;

	printf("请输入税前总收入:");
	scanf("%lf", &income);

	if (income <= kind)
		tax = income * TAXD;
	else
		tax = kind * TAXD + (income - kind) * TAXU;

	printf("应付税金为:%.2lf\n", tax);
	
}



11. ABC Mail Order Grocery朝鲜蓟的售价是1.25美元/磅,甜菜的售价是0.65美元/磅,胡萝卜的售价是0.89美元/磅。在添加运输费用之前,他们为100美元的订单提供5%的打折优惠。对5磅或以下的定单收取3.50美元的运输和装卸费用;超过5磅而不足20磅的定单收取1O.OO美元的运输和装卸费用:20磅或以上的运输,在8美元基础上每磅加收0.1美元。编写程序,在循环中使用switch语句,以便对输入a的响应是让用户输入所需的朝鲜蓟磅数,b为甜菜的磅数,c为胡萝卜的磅数,而q允许用户退出订购过程。然后程序计算总费用、折扣和运输费用(如果有运输费的话),以及总数。随后程序应该显示所有的购买信息:每磅的费用、订购的磅数、该订单每种蔬菜的费用、订单的总费用、折扣,如果有的话加上运输费用,以及所有费用的总数。

#include <stdio.h>
#define PRICE 100
#define DISCOUNT_RATE 0.05

void menu(void);
double in_lb(void);
void empty(void);

int main(void)
{
	const double price_a = 1.25;
	const double price_b = 0.65;
	const double price_c = 0.89;

	char ch;
	double lb_a = 0.00;
	double lb_b = 0.00;
	double lb_c = 0.00;
	double lb_total = 0.00;

	double cost_a = 0.00;
	double cost_b = 0.00;
	double cost_c = 0.00;
	double cost_total = 0.00;
	double final_total = 0.00;
	double discount = 0.00;
	double shipping = 0.00;

	menu();

	while ((ch = getchar()) != 'q')
	{
		empty();
		switch (ch)
		{
		case 'a': lb_a += in_lb(); empty();
			break;
		case 'b': lb_b += in_lb(); empty();
			break;
		case 'c': lb_c += in_lb(); empty();
			break;
		default: printf("请输入正确的选项(a b c or q):");
		}
		menu();
		
	}
	
	//总费用
	cost_a = price_a * lb_a;
	cost_b = price_b * lb_b;
	cost_c = price_c * lb_c;
	lb_total = lb_a + lb_b + lb_c;
	cost_total = cost_a + cost_b + cost_c;

	//折扣
	if (cost_total > PRICE)
		discount = cost_total * DISCOUNT_RATE;

	//运输费用
	if (lb_total < 5)
		shipping = 3.50;
	else if (lb_total < 20)
		shipping = 10.00;
	else
		shipping = 8 + (int)lb_total * 0.10;


	printf("\n订单详情:\n");
	printf("朝鲜蓟单价$%.2f。	%.2f磅总价$%.2f\n", price_a, lb_a, cost_a);
	printf("甜菜单价$%.2f。		%.2f磅总价$%.2f\n", price_b, lb_b, cost_b);
	printf("胡萝卜单价$%.2f。	%.2f磅总价$%.2f\n", price_c, lb_c, cost_c);
	printf("蔬菜的总费用:%.2lf\n", cost_total);
	printf("折扣:%.2lf\n", discount);
	printf("运输费用:%.2lf\n", shipping);
	printf("应付的费用:%.2lf\n", cost_total  - discount);

	return 0;
}

void menu(void)
{
	printf("请选择类别:\n");
	printf("	a)朝鲜蓟		b)甜菜\n");
	printf("	c)胡萝卜		q)退出\n");
}

double in_lb(void)
{
	double a;

	printf("请输入重量:");
	scanf("%lf", &a);

	return a;
}

void empty(void)
{
	while (getchar() != '\n')
		;
}