《C Prime Plus》(第六版) 第07章 C控制语句:分支和跳转 例题集和编程练习

  • OS: Mac Catalina 10.15.4 
  • Hardware: Intel Core i9/16G 2667MHz DDR4
  • 编译器版本:Mac Xcode 11.6 

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


目录

例题

例题1 读入温度列表求低于0摄氏度以下占总天数的百分比

例题2 getchar()和putchar()的使用

例题3 利用isalpha()来判断读入的字符是否是字母

例题4  多重选择else if的一个求电费的例子

例题5 嵌套循环,求整数的约数

例题 6 逻辑运算符,求除单引号和双引号以外其他字符的数量

例题 7 统计字符数、单词数、行数

例题 8 条件运算符 ? :计算油漆桶数量

例题 9 continue跳过部分循环

例题 10 break语句,跳出当前循环

例题 11 switch和break语句

例题 12 使用switch实现多重标签

编程练习

习题 1

习题 2

 习题 3

习题 4

 习题 5

习题 6

习题 7

 习题 8

 习题 9

 习题 10

 习题 11


例题

例题1 读入温度列表求低于0摄氏度以下占总天数的百分比

// colddays.c -- 找出0摄氏度以下的天数占总天数的百分比
#include <stdio.h>

int main(void)
{
    const int FREEZING = 0;
    float temperature;
    int cold_days = 0;
    int all_days = 0;
    
    printf("Enter the list of daily low temperatures.\n");
    printf("Use Celsius, and enter q to quit.\n");
    while (scanf("%f", &temperature) == 1)
    {
        all_days++;
        if (temperature < FREEZING)
            cold_days++;
    }
    if (all_days != 0)
        printf("%d days total: %.1f%% were below freezing.\n",
               all_days, 100.0 * (float) cold_days / all_days);
    if (all_days == 0)
        printf("No data entered!\n");
    
    return 0;
}

程序输出结果:

注意:

  • 100.0 * (float) cold_days / all_days为现实转换,有利于程序阅读
  • 第2个if语句可使用else替换

例题2 getchar()和putchar()的使用

如果字符是空白,则原样打印,否则,打印原字符在ASCII序列中的下一个字符

// cypher1.c -- 更改输入,空格不变
#include <stdio.h>
#define SPACE ' '           // SPACE表示单引号-空格-单引号

int main(void)
{
    char ch;
    
    ch = getchar();             // 读取一个字符
    while (ch != '\n')          // 当一行末结束时
    {
        if (ch == SPACE)        // 留下空格
            putchar(ch);        // 该字符不变
        else
            putchar(ch + 1);    // 改变其他字符
        ch = getchar();         // 获取下一个字符
    }
    putchar(ch);                // 打印换行符
    
    return 0;
}

程序输出结果:

 注意:

  • getchar()和putchar()只支持字符。
  • ch = getchar()等同于scanf("%c", ch);
  • putchar(ch)等同于printf("%c", ch);

例题3 利用isalpha()来判断读入的字符是否是字母

#include <stdio.h>
#include <ctype.h>              // 包含isalpha()的函数原型

int main(void)
{
    char ch;
    
    while ((ch = getchar()) != '\n')
    {
        if (isalpha(ch))        // 如果是一个字符
            putchar(ch + 1);    // 显示该字符的下一个字符
        else                    // 否则
            putchar(ch);        // 原样显示
    }
    putchar(ch);                // 显示换行符
    
    return 0;
}

程序输出:

 注意:

  • isalpha()原型定义在ctype.h头文件里
  • ctype其它一些常用函数见表7.1和7.2(page 183)

例题4  多重选择else if的一个求电费的例子

// electric.c -- 计算电费
#include <stdio.h>

#define RATE1   0.13230             // 首次使用360kwh的费率
#define RATE2   0.15040             // 接着再使用108kwh的费率
#define RATE3   0.30025             // 接着再使用252kwh的费率
#define RATE4   0.34025             // 使用超过720kwwh的费率
#define BREAK1  360.0               // 费率的第1个分界点
#define BREAK2  468.0               // 费率的第2个分界点
#define BREAK3  720.0               // 费率的第3个分界点
#define BASE1   (RATE1 * BREAK1)                                // 使用360kwh的费用
#define BASE2   (BASE1 + (RATE2 * (BREAK2 - BREAK1)))           // 使用468kwh的费用
#define BASE3   (BASE1 + BASE2 + (RATE3 * (BREAK3 - BREAK2)))   // 使用720kwh的费用

int main(void)
{
    double kwh;                     // 使用的千瓦时
    double bill;                    // 电费
    
    printf("Please enter the kwh used.\n");
    scanf("%lf", &kwh);             // %lf对应double类型
    if (kwh < BREAK1)
        bill = RATE1 * kwh;
    else if (kwh <= BREAK2)         // 30~468kwh
        bill = BASE1 + (RATE2 * (kwh - BREAK1));
    else if (kwh <= BREAK3)         // 468~720kwh
        bill = BASE2 + (RATE3 * (kwh - BREAK2));
    else                            // 超过720kwh
        bill = BASE3 + (RATE4 * (kwh - BREAK3));
    
    printf("The charge for %.1f kwh is $%1.2f.\n", kwh, bill);
    
    return 0;
}

程序输出:

注意:

  • else 与最近的一个if配对 

例题5 嵌套循环,求整数的约数

// divisors.c -- 使用嵌套if语句显示一个数的约数
#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    unsigned long num;  // 待测试的数
    unsigned long div;  // 可能的约数
    bool isPrime;       // 素数标记
    
    printf("Please enter an integer for analysis; ");
    printf("Enter q to quit.\n");
    while (scanf("%lu", &num) == 1)
    {
        for (div = 2, isPrime = true; (div * div) <= num; div++)
        {
            if (num % div == 0)
            {
                if ((div * div) != num)
                    printf("%lu is divisible by %lu and %lu.\n",
                           num, div, num / div);
                else
                    printf("%lu is divisible by %lu.\n",
                           num, div);
                isPrime = false;        // 该数不是素数
            }
        }
        if (isPrime)
            printf("%lu is prime.\n", num);
        printf("Please enter another integer for analysis; ");
        printf("Enter q to quit.\n");
    }
    printf("Bye.\n");
    
    return 0;
}

程序输出:

 注意:

  • 整数求约数不会超过这个数的开根
  • 使用div*div整数速度比实数开根更快
  • <stdbool.h>包含了bool, true, false的定义,若编译器不支持,可使用int替换

例题 6 逻辑运算符,求除单引号和双引号以外其他字符的数量

// chcount.c -- 使用逻辑与运算符
#include <stdio.h>
#define PERIOD '.'

int main(void)
{
    char ch;
    int charcount = 0;
    
    while ((ch = getchar()) != PERIOD)
    {
        if (ch != '"' && ch != '\'')
            charcount++;
    }
    printf("There are %d non-quote characters.\n", charcount);
    
    return 0;
}

程序输出:

 注意:

  • &&运算符,当第一个表达式为假,后面的表达式不再求解

例题 7 统计字符数、单词数、行数

// wordcnt.c -- 统计字符数、单词数、行数
#include <stdio.h>
#include <ctype.h>      // 为isspace()函数提供原型
#include <stdbool.h>    // 为bool、true、false提供定义
#define STOP '|'

int main(void)
{
    char c;                 // 读入字符
    char prev;              // 读入的前一个字符
    long n_chars = 0L;      // 字符数
    int n_lines = 0;        // 行数
    int n_words = 0;        // 单词数
    int p_lines = 0;        // 不完整的行数
    bool inword = false;    // 如果c在单词中, inword等于true
    
    printf("Enter text to be analyzed (| to terminate):\n");
    prev = '\n';            // 用于识别完整的行
    while ((c = getchar()) != STOP)
    {
        n_chars++;          // 统计字符数
        if (c == '\n')
            n_lines++;      // 统计行
        if (!isspace(c) && !inword)
        {
            inword = true;  // 开始一个新的单词
            n_words++;      // 统计单词
        }
        if (isspace(c) && inword)
        {
            inword = false; // 达到单词的末尾
        }
        prev = c;           // 保存字符的值
    }
    
    if (prev != '\n')
        p_lines = 1;
    printf("characters = %ld, words = %d, lines = %d, ", n_chars, n_words, n_lines);
    printf("partical lines = %d\n", p_lines);
    
    return 0;
}

程序输出:

 注意:

  • 使用isspace()来代替c == ' ' || c == '\n' || c == '\t'
  • isspace()的定义在<ctype.h>里
  • 字符计数使用long int

例题 8 条件运算符 ? :计算油漆桶数量

// paint.c -- 使用条件运算符
#include <stdio.h>
#define COVERAGE 350        // 每罐油漆可刷的面积(单位:平方英尺)

int main(void)
{
    int sq_feet;
    int cans;
    
    printf("Enter number of square feet to be painted:\n");
    while (scanf("%d", &sq_feet) == 1)
    {
        cans = sq_feet / COVERAGE;
        cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1;
        printf("You need %d %s of paint.\n", cans,
               cans == 1 ? "can" : "cans");
        printf("Enter next value (q to quit):\n");
    }
    
    return 0;
}

程序输出:

 注意:

  • cans是int类型,在计算sq_feet / COVERAGE时会被强制截断
  • 使用cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1; 来判断是否有余数,如果有则+1(油漆桶按桶销售)

例题 9 continue跳过部分循环

// skippart.c -- 使用continue跳过部分循环
#include <stdio.h>

int main(void)
{
    const float MIN = 0.0f;
    const float MAX = 100.0f;
    
    float score;
    float total = 0.0f;
    int n = 0;
    float min = MAX;
    float max = MIN;
    
    printf("Enter the first score (q to quit): ");
    while (scanf("%f", &score) == 1)
    {
        if (score < MIN || score > MAX)
        {
            printf("%0.1f is invalid value. Try again: ", score);
            continue;       // 跳转至while循环的测试条件
        }
        printf("Accepting %0.1f:\n", score);
        min = (score < min) ? score : min;
        max = (score > max) ? score : max;
        total += score;
        n++;
        printf("Enter next score (q to quit): ");
    }
    if (n > 0)
    {
        printf("Average of %d scores is %0.1f.\n", n, total / n);
        printf("Low = %0.1f, high = %0.1f\n", min, max);
    }
    else
        printf("No valid scores were entered.\n");
    
    return 0;
}

程序输出:

例题 10 break语句,跳出当前循环

// break.c -- 使用break退出循环
#include <stdio.h>

int main(void)
{
    float length, width;
    
    printf("Enter the length of the rectangle:\n");
    while (scanf("%f", &length) == 1)
    {
        printf("Length = %0.2f:\n", length);
        printf("Enter its width:\n");
        if (scanf("%f", &width) != 1)
            break;
        printf("Width = %0.2f:\n", width);
        printf("Area = %0.2f:\n", length * width);
        printf("Enter the length of the rectangle:\n");
    }
    printf("Done.\n");
    
    return 0;
}

程序输出:

例题 11 switch和break语句

// animals.c -- 使用switch语句
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char ch;
    
    printf("Give me a letter of the alphabet, and I will geive ");
    printf("an animal name\nbeginning with that letter.\n");
    printf("Please type in a letter; type # to end my act.\n");
    while ((ch = getchar()) != '#')
    {
        if ('\n' == ch)
            continue;
        if (islower(ch))        /* 只接受小写字母 */
        {
            switch(ch)
            {
                case 'a':
                    printf("argali, a wild sheep of Asia\n");
                    break;
                case 'b':
                    printf("babirusa, a wild pig of Malay\n");
                    break;
                case 'c':
                    printf("coati, racoonlike mammal\n");
                    break;
                case 'd':
                    printf("desman, aquatic, molelike critter\n");
                    break;
                case 'e':
                    printf("echidna, the spiny anteater\n");
                    break;
                default:
                    printf("That's a stumper!\n");
            } /* switch 结束 */
        } else
            printf("I recognize only lowercase letter.\n");
        while (getchar() != '\n')
            continue;   /* 跳过输入行的剩余部分 */
        printf("Please type another letter or a #.\n");
    }
    printf("Bye!\n");
    
    return 0;
}

程序输出:

注意:

使用下面的代码来跳过多输入的字符

while (getchar() != '\n')
    continue;   /* 跳过输入行的剩余部分 */

使用下面的代码来跳过不输入任何文字就回车

if ('\n' == ch)
    continue;

例题 12 使用switch实现多重标签

// vowels.c -- 使用多重标签
#include <stdio.h>

int main(void)
{
    char ch;
    int a_ct, e_ct, i_ct, o_ct, u_ct;
    
    a_ct = e_ct = i_ct = o_ct = u_ct = 0;
    
    printf("Enter some text; enter # to quit.\n");
    while ((ch = getchar()) != '#')
    {
        switch (ch)
        {
            case 'a':
            case 'A':
                a_ct++;
                break;
            case 'e':
            case 'E':
                e_ct++;
                break;
            case 'i':
            case 'I':
                i_ct++;
                break;
            case 'o':
            case 'O':
                o_ct++;
                break;
            case 'u':
            case 'U':
                u_ct++;
                break;
            default:
                break;
        } // switch结束
    }   // while 结束
    printf("number of vowels:  A    E    I    O    U\n");
    printf("                %4d %4d %4d %4d %4d\n",
           a_ct, e_ct, i_ct, o_ct, u_ct);
    
    return 0;
}

程序输出:

 注意:

  • case 只能用做char,int型

编程练习

习题 1

编写一个程序读取输入,读到#字符停止,然后报告读取的空格数、换行符数和其他字符的数量

#include <stdio.h>

int main(void)
{
    char ch;
    unsigned int space_count, return_count, other_count;
    
    space_count = return_count = other_count = 0;
    
    printf("输入字符序列,#字符表示读取截止:\n");
    while ((ch = getchar()) != '#')
    {
        if (ch == ' ')
            space_count++;
        else if (ch == '\n')
            return_count++;
        else
            other_count++;
    }
    printf("空格数:%4d 换行符数:%4d 其他字符数:%4d\n",
           space_count, return_count, other_count);
    printf("Done.\n");
    
    return 0;
}

程序输出:

  

习题 2

编写一个程序读取输入,读到#字符停止。程序要打印每个输入的字符以及对应的ASCII码(十进制)。每行打印8个“字符-ASCII码“组合。建议:使用字符计数和求模运算符(%)在每8个循环周期时打印一个换行符。

#include <stdio.h>

int main(void)
{
    char ch;
    unsigned int count;
    
    count = 0;
    
    printf("输入一串字符,使用#结束输入:\n");
    while ((ch = getchar()) != '#')
    {
        printf("%c-%-4d", ch, ch);
        if(++count % 8 == 0)
            printf("\n");
        else
            printf("    ");
    }
    printf("\nDone.\n");
    
    return 0;
}

程序输出:

 习题 3

// 2. 编写一个程序,读取整数直到用户输入0。输入结束后,程序应报告用户输入的偶数>(不包括0)
// 个数、这些偶数的平均值、输入的奇数个数及其奇数的平均值

#include <stdio.h>

int main(void)
{
        int var = 0;                                    // 读取整数暂存变量
        int sumEven, sumOdd, countEven, countOdd;       // 偶数求、奇数求和变量;偶数、奇数个数变量
        sumEven = sumOdd = 0;                           // 变量初始化
        countEven = countOdd = 0;

        printf("输入整数,整数之间使用空格间隔,输入0表示输入结束.\n");
        printf("开始输入:");

        scanf("%d", &var);                              // 读取整数输入
        while(var != 0)                                 // 只要不是0,则区分奇偶
        {
                if(var % 2 == 0)                        // 偶数
                {
                        sumEven += var;                 // 偶数求和
                        countEven++;                    // 偶数求个数
                }
                else                                    // 奇数
                {
                        sumOdd += var;                  // 奇数求和
                        countOdd++;                     // 奇数求个数
                }
                scanf("%d", &var);                      // 读取下一个
        }

        printf("偶数个数: %d,偶数合计: %d,偶数平均值: %f\n",          // 输出>偶数,平均值使用强制类型转换
                countEven, sumEven, (float)sumEven / countEven);
        printf("奇数个数: %d,奇数合计: %d,奇数平均值: %f\n",          // 输出>奇数,平均值使用强制类型转换
                countOdd, sumOdd, (float)sumOdd / countOdd);

        return 0;
}

习题 4

// 4. 使用if else语句编写一个程序读取输入,读到#停止。用感叹号替换语句,用两个感
叹号替换原来
// 的感叹号,最后报告进行了多少次替换。

#include <stdio.h>
#include <ctype.h>

int main(void)
{
        char ch;                // 读入字符暂存变量
        int count = 0;          // 替换次数计数器,初始化0

        printf("读入字符直到读到#停止。用两个感叹号替换原来的感叹号,并计算替换>了几次\n");
        printf("开始输入:");

        while ((ch = getchar()) != '#')                 // 读入字符串,直到遇到#为止
        {
                if (ch == '!')                          // 如果字符为感叹号则开>始替换
                {
                        putchar(ch);                    // 输出两个感叹号
                        putchar(ch);
                        count++;                        // 替换次数+1
                }
                else
                        putchar(ch);                    // 不是感叹号的原样输出
        }
        printf("\n一共进行了 %d 次替换.\n", count);     // 打印提示

        return 0;
}

 习题 5

// 5. 使用switch重写联系4
  
#include <stdio.h>
#include <ctype.h>

int main(void)
{
        char ch;                // 读入字符暂存变量
        int count = 0;          // 替换次数计数器,初始化0

        printf("读入字符直到读到#停止。用两个感叹号替换原来的感叹号,并计算替换>了几次\n");
        printf("开始输入:");

        while ((ch = getchar()) != '#')                 // 读入字符串,直到遇到#为止
        {
                switch (ch)
                {
                        case '!':                       // 如果字符为感叹号则开>始替换
                                putchar(ch);            // 输出两个感叹号
                                putchar(ch);
                                count++;                // 替换次数+1
                                break;
                        default:
                                putchar(ch);            // 不是感叹号的原样输出
                }
        }
        printf("\n一共进行了 %d 次替换.\n", count);     // 打印提示

        return 0;
}

习题 6

// 6. 编写程序读取输入,读到#停止,报告ei出现的次数。
// 注意:
//    该程序要记录前一个字符和当前字符。用"Receive your eieio award"这样的输入来
测试。

#include <stdio.h>

int main(void)
{
        int counter = 0;                                // ei出现次数计数器
        char ch, prChar = 0;                            // 当前字符,前一字符

        printf("报告ei出现的次数,可以用\"Receive your eieio award\"来测试.\n");
        printf("输入文字,#结束:");

        while ((ch = getchar()) != '#')                 // 读入字符直到遇到#为止
        {
                if ((ch == 'i') && (prChar == 'e'))     // 当前字符是i且前一字符
是e
                        counter++;                      // 计数器+1
                prChar = ch;                            // 当前字符被赋值给前一>字符暂存起来
        }
        printf("\"ei\"共出现了 %d 次.\n", counter);     // 输出次数

        return 0;
}

习题 7

// 7. 编写一个程序,提示用户输入一周工作的小时数,然后打印工资总额、税金和净收入。做如下假设:
//      a. 基本工资=10.00美元/小时
//      b. 加班(超过41小时)=1.5倍的时间
//      c. 税率: 前301美元为15%
//                续151美元为20%
//                余下的为26%
//    用#define定义符号常量。不用在意是否符合当前的税法

#include <stdio.h>

#define BASE_PER_HOUR 	 10.00		// 每小时的基本工资
#define OVER_TIME 		 40.0		// 加班时数分界点
#define OVER_TIME_POWER  1.5		// 加班的时数倍率
#define GRADE_1			 300.0		// 第一阶段<=300美元
#define GRADE_2			 450.0		// 第二阶段300< n <= 450.0美元
#define TAX_GRADE_1		 0.15		// 前300美元为15%
#define TAX_GRADE_2		 0.20		// 续150美元为20%
#define TAX_GRADE_3		 0.25		// 余下为25%

int main(void)
{
	float hoursOfWeek, sumSalary, baseSalary, overTimePay, tax;
	hoursOfWeek = sumSalary = baseSalary = overTimePay = tax = 0;

	printf("输入一周工作的小时数:");
	scanf("%f", &hoursOfWeek);

	if (hoursOfWeek <= OVER_TIME)	
		baseSalary = BASE_PER_HOUR * hoursOfWeek;					// 基本工资总额
	else // 如果上班时数超过40小时
	{
		baseSalary = OVER_TIME * BASE_PER_HOUR;						// 基本工资总额
		overTimePay = (hoursOfWeek - OVER_TIME) * OVER_TIME_POWER	// 加班工资总额
			* BASE_PER_HOUR;									
	}
	sumSalary = baseSalary + overTimePay;							// 工资总额=基本工资+加班工资
	
	if (sumSalary <= GRADE_1)										// 如果在第一阶梯内则使用前300美元*15%
		tax = sumSalary * TAX_GRADE_1;
	else if ((sumSalary > GRADE_1) && (sumSalary <= GRADE_2))		// 如果在第二阶梯,则前300美元*20%,余下*25%
		tax = GRADE_1 * TAX_GRADE_1 + (sumSalary - GRADE_1) * TAX_GRADE_2;
	else	// 如果在第三阶梯,则第1阶段+第2阶段+余下*25%执行
		tax = GRADE_1 * TAX_GRADE_1
			+ (GRADE_2 - GRADE_1) * TAX_GRADE_2
			+ (sumSalary - GRADE_2) * TAX_GRADE_3;

	printf("基本工资总额(小时数*基本工资): %f\n", baseSalary);
	printf("加班工资总额(超出部分的小时数*倍率*基本工资): %f\n", overTimePay);
	printf("工资总额(基本工资+加班工资): %f\n", sumSalary);
	printf("应纳税额(税金): %f\n", tax);
	printf("净收入(工资总额-税金): %f\n", sumSalary - tax);

	return 0;
}

 习题 8

// 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创建符号常量表示各工资等级和税率

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

#define OVER_TIME          	40.0        // 加班时数分界点
#define OVER_TIME_POWER  	1.5        	// 加班的时数倍率
#define GRADE_1             300.0  		// 第一阶段<=300美元
#define GRADE_2             450.0   	// 第二阶段300< n <= 450.0美元
#define TAX_GRADE_1         0.15        // 前300美元为15%
#define TAX_GRADE_2         0.20        // 续150美元为20%
#define TAX_GRADE_3         0.25        // 余下为25%

int main(void)
{
    float hoursOfWeek, sumSalary, baseSalary, overTimePay, tax, basePerHour;
	char ch = 0, c;			// 选择菜单项目,清除输入缓存
	bool menuSelectFail = false;	// 选择失败标记
    hoursOfWeek = sumSalary = baseSalary = overTimePay = tax = 0;

	while (ch != '5')		// 选择菜单=5时推出循环,否则进入循环
	{
		// 显示菜单
		printf("****************************************************************\n");
		printf("Enter the number corresponding to the desired pay rate or action:\n");
		printf("   1) $8.75/hr           2) $9.33/hr\n");
		printf("   3) $10.00/hr          4) $11.20/hr\n");
		printf("   5) quit\n");
		printf("****************************************************************\n");
		
		printf("Please input menu item:");				// 提示输入菜单项目
		ch = getchar();
		while ((c = getchar()) != EOF && c != '\n');	// 读入第一个字符并将后续缓存清空

		menuSelectFail = false;			// 默认菜单选择成功
		switch(ch)
		{
			case '1':
				basePerHour = 8.75;		// 菜单1
				break;
			case '2':
				basePerHour = 9.33;		// 菜单2
				break;
			case '3':
				basePerHour = 10.00;	// 菜单3
				break;
			case '4':
				basePerHour = 11.22;	// 菜单4
				break;
			case '5':
				menuSelectFail = true;	// 设置菜单选择失败
				break;
			default:
				menuSelectFail = true;	// 设置菜单选择失败
				printf("输入1~4选择每小时工资。输入5退出程序.\n");	// 提示并重新让选择
		}

		if (menuSelectFail) continue;	// 如果菜单失败则进入下一轮循环

    	printf("输入一周工作的小时数:");	// 提示输入小时数
    	scanf("%f", &hoursOfWeek);
		setbuf(stdin, NULL);				// 清空键盘缓存

    	if (hoursOfWeek <= OVER_TIME)
        	baseSalary = basePerHour * hoursOfWeek;                    // 基本工资总额
    	else // 如果上班时数超过40小时
    	{
        	baseSalary = OVER_TIME * basePerHour;                        // 基本工资总额
        	overTimePay = (hoursOfWeek - OVER_TIME) * OVER_TIME_POWER    // 加班工资总额
            	* basePerHour;
    	}
    	sumSalary = baseSalary + overTimePay;                            // 工资总额=基本工资+加班工资
    
    	if (sumSalary <= GRADE_1)                                        // 如果在第一阶梯内则使用前300美元*15%
        	tax = sumSalary * TAX_GRADE_1;
    	else if ((sumSalary > GRADE_1) && (sumSalary <= GRADE_2))        // 如果在第二阶梯,则前300美元*20%,余下*25%
        	tax = GRADE_1 * TAX_GRADE_1 + (sumSalary - GRADE_1) * TAX_GRADE_2;
    	else    // 如果在第三阶梯,则第1阶段+第2阶段+余下*25%执行
        	tax = GRADE_1 * TAX_GRADE_1
				+ (GRADE_2 - GRADE_1) * TAX_GRADE_2
            	+ (sumSalary - GRADE_2) * TAX_GRADE_3;

    	printf("基本工资总额(小时数*基本工资): %f\n", baseSalary);
    	printf("加班工资总额(超出部分的小时数*倍率*基本工资): %f\n", overTimePay);
    	printf("工资总额(基本工资+加班工资): %f\n", sumSalary);
    	printf("应纳税额(税金): %f\n", tax);
    	printf("净收入(工资总额-税金): %f\n", sumSalary - tax);
	}

    return 0;
}

 习题 9

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

#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>

int main(void)
{
	int n, i, j;
	n = i = j = 0;
	bool prime = false;
	
	printf("输入一个正整数: ");
	scanf("%d", &n);
	if(n <= 0)
	{
		printf("必须输入一个正整数\n");
		return 1;
	}

	for(i = n; i > 1; i--)
	{
		prime = true;
		for(j = 2; j < i; j++)
		{
			if (i % j == 0)
			{
				prime = false;
				break;
			}
		}
		if(prime)
			printf("%6d", j);
	}
	printf("\n");
	
	return 0;
}

 习题 10

// 10. 1988年美国联邦税收计划是近代最简单的税收方案。它分为4个类别,每个类别有两个等级。
//     下面是该税收计划的摘要(美元数为应征税的收入):
//     ---------------------------------------------------------------------
//     类别               | 税金
//     ---------------------------------------------------------------------
//       单身             | 17850美元按15%计,超出部分按28%计
//       户主             | 23900美元按15%计,超出部分按28%计
//       已婚,共有       | 29750美元按15%计,超出部分按28%计
//       已婚,离异       | 14875美元按15%计,超出部分按28%计
//     ---------------------------------------------------------------------
//     例如,一位工资为20000美元的单身纳税人,应缴纳税费0.15*17850+0.28*(20000-17850)美
//     元。编写一个程序,让用户指定缴纳税金的种类和应纳税收入,然后计算税金。程序应通过循环
//     让用户可以多次输入。

#include <stdio.h>
#include <stdbool.h>

#define GRADE_1		0.15		// 第一阶梯,15%
#define GRADE_2		0.28		// 第二阶梯,28%

int main(void)
{
	char ch = 0, c;						// 菜单选择
	bool menuSelectFail = false;		// 选择失败标志
	float salary, salaryGrade, tax;		// 工资收入,工资等级分界线,税额

	salary = salaryGrade = tax = 0;		// 初始化变量

	while (ch != '5')					// 输入5则退出程序
	{
		printf("*********************************************I*************\n");	// 显示菜单
		printf("   1) 单身    		17850美元按15%%计,超出部分按28%%计\n");
		printf("   2) 户主    		23900美元按15%%计,超出部分按28%%计\n");
		printf("   3) 已婚,共有	29750美元按15%%计,超出部分按28%%计\n");
		printf("   4) 已婚,离异	14875美元按15%%计,超出部分按28%%计\n");
		printf("   5) 退出\n");
		printf("***********************************************************\n");
		printf("按1~4选择类型,按5退出: ");
		scanf("%c", &ch);								// 输入菜单项
		while ((c = getchar()) != EOF && c != '\n');	// 读取第一个字符后,后面的字符清空

		menuSelectFail = false;	// 默认菜单选择有效
		switch (ch)		// 依据菜单选择设定不同的工资分界值
		{
			case '1':
				salaryGrade = 17850.0;
				break;
			case '2':
				salaryGrade = 23900.0;
				break;
			case '3':
				salaryGrade = 29750.0;
				break;
			case '4':
				salaryGrade = 14875.0;
				break;
			case '5':		// 选择5,仅设置菜单选择失败
				menuSelectFail = true;
				break;
			default:		// 其他输入,提示输入失败重新输入
				menuSelectFail = true;
				printf("输入错误,输入1~4选择类型,按5退出\n");
		}
		
		if (menuSelectFail) continue;	// 如果菜单选择失败则退出循环

		printf("输入工资金额:");		// 如果税前工资
		scanf("%f", &salary);
		setbuf(stdin, NULL);			// 清除键盘缓冲区

		if (salary <= salaryGrade)		// 当处于第一阶范围内,则按第一阶计算		
			tax = salary * GRADE_1;
		else							// 超过一阶则按第一阶+第二阶计算
			tax = salaryGrade * GRADE_1 + (salary - salaryGrade) * GRADE_2;
		
		printf("应纳税金额: %f\n", tax);			// 输出纳税金额
		printf("税后净收入: %f\n", salary - tax);	// 输出净收入
	}

	return 0;
}

 习题 11

// 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磅的甜菜。然后,该程序要计算货物总价、折扣(如果有的话)、运费和
// 		包装费。随后,程序应显示所有的购买信息:物品售价、订购的重量(单位:磅)、订购的蔬菜费
// 		用,订单的总费用、折扣(如果有的话)、运费和包装费,以及所有的费用总额。

#include <stdio.h>
#include <stdbool.h>

#define ITEM_PRICE_1 	2.05	// 洋芋每磅单价
#define ITEM_PRICE_2	1.15	// 甜菜每磅单价
#define ITEM_PRICE_3	1.09	// 胡萝卜每磅单价

void showMenu(void);					// 显示菜单
float packingCharges(float weight);		// 包装费+运费
float discount(float pay);				// 计算折扣

int main(void)
{
	float fDiscount, fPay, fPacking, fSumWeight, weight;
	float fWeightItem1, fWeightItem2, fWeightItem3;
	float fPayItem1, fPayItem2, fPayItem3;
	bool selectMenuFail;
	char ch = 0, c;

	fWeightItem1 = fWeightItem2 = fWeightItem3 = 0;		// 初始化变量
	fPayItem1 = fPayItem2 = fPayItem3 = 0;

	while (ch != 'q')	// 如果输入字符是q则立即退出程序
	{
		showMenu();	// 显示菜单

		printf("请选择购买的商品(a,b,c),按(q)退出:");
		scanf("%c", &ch);			// 读入菜单选择项目
		while ((c = getchar()) != EOF && c != '\n');	// 读取第一个字符后,后面的字符清掉

		selectMenuFail = false;
		switch (ch)
		{
			case 'a': // 选择洋芋
				printf("请输入购买商品的重量(单位:磅):");
				scanf("%f", &weight);
				setbuf(stdin, NULL);		// 清除键盘缓冲区
				fWeightItem1 = fWeightItem1 + weight;
				fPayItem1 = fWeightItem1 * ITEM_PRICE_1;
				break;
			case 'b': // 选择甜菜
				printf("请输入购买商品的重量(单位:磅):");
				scanf("%f", &weight);
				setbuf(stdin, NULL);		// 清除键盘缓冲区
				fWeightItem2 = fWeightItem2 + weight;
				fPayItem2 = fWeightItem2 * ITEM_PRICE_2;
				break;
			case 'c': // 选择胡萝卜
				printf("请输入购买商品的重量(单位:磅):");
				scanf("%f", &weight);
				setbuf(stdin, NULL);		// 清除键盘缓冲区
				fWeightItem3 = fWeightItem3 + weight;
				fPayItem3 = fWeightItem3 * ITEM_PRICE_3;
				break;
			case 'q':
				selectMenuFail = true;
				break;
			default:
				selectMenuFail = true;
				printf("输入错误,请选择购买的商品(a,b,c),按(q)退出\n");
		}

		if (selectMenuFail) continue;		// 如果菜单选择失败则忽略并重新显示菜单

		fPay = fPayItem1 + fPayItem2 + fPayItem3; // 金额合计=洋芋金额+甜菜金额+胡萝卜金额
		fSumWeight = fWeightItem1 + fWeightItem2 + fWeightItem3;	// 总重量=洋芋重量+甜菜重量+胡萝卜重量

		fDiscount = discount(fPay);	// 计算折扣
		fPacking = packingCharges(fSumWeight); // 计算包装及运费

		printf("------------  采购清单如下 -----------------\n");
		printf(" a. 洋芋   金额: %10.2f  重量: %10.2f磅\n", fPayItem1, fWeightItem1);
		printf(" b. 甜菜   金额: %10.2f  重量: %10.2f磅\n", fPayItem2, fWeightItem2);
		printf(" c. 胡萝卜 金额: %10.2f  重量: %10.2f磅\n", fPayItem3, fWeightItem3);
		printf("--------------------------------------------\n");
		printf("合计:      金额(+): %10.2f    重量: %10.2f磅\n", fPay, fSumWeight);	 // 输出结算
		printf("-----------折扣(-): %10.2f\n", fDiscount);
		printf("-----------运费(+): %10.2f\n", fPacking);
		printf("----------应付总额: %10.2f\n", fPay - fDiscount + fPacking);
	}

	return 0;
}

void showMenu(void)
{
	printf("*************  menu  *******************\n");
	printf("  a) 洋芋    $2.05/pound\n");
	printf("  b) 甜菜    $1.15/pound\n");
	printf("  c) 胡萝卜  $1.09/pound\n");
	printf("  q) 退出\n");
	printf("****************************************\n");
}

float discount(float pay)
{
	return (int)(pay / 100) * (100.0 * 0.05);
}

float packingCharges(float weight)
{
	if (weight <= 5.0)
		return 6.5;
	else if (weight > 5.0 && weight <= 20)
		return 14.0;
	else
		return 14.0 + (weight - 20.0) * 0.5;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值