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


title: 第七章 C控制语句:分支和跳转
author: HardyDragon
tags: C Notes


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

7.1 if语句

7.2 if else语句

7.2.1 介绍getchar()

7.2.2 ctype.h 系列的字符函数

7.2.3 多重选择else if

7.2.4 else与if配对

7.2.5 多层嵌套的if语句

7.3 逻辑运算符

7.3.1 备选拼写:iso646.h 头文件

7.3.2 优先级

7.3.3 求值顺序

7.3.4 范围

7.4 一个统计单词的程序

7.5 条件运算符:?:

7.6 循环辅助:continue和break

7.6.1 continue语句

7.6.2 break语句

7.7 多重选择

7.7.1 switch语句

7.7.2 只读每行的首字符

7.7.3 多重标签

7.7.2 swtich和if else

7.8 goto语句

7.9 关键概念

7.10 本章小结

7.11 复习题

7.12 编程练习


7.1 if语句

// colddays.c -- 找出0摄氏度的天数占总天数的百分比
#include <stdio.h>
int main(int argc, char const *argv[])
{
    
    
    const int FREEZING = 0;
    float temperature = 0;
    int cold_days = 0;
    int all_days = 0;

    printf("输入每日的最低温度列表:(q退出)\n");
    while (scanf("%f", &temperature) == 1)
    {
    
    
        /* code */
        all_days++;
        if (temperature < FREEZING)
        {
    
    
            cold_days++;
        }
    }

    if (all_days != 0)
    {
    
    
        printf("一共 %d 天,其中 %.1f%% 天都是极冷的。\n ", all_days, 100.0* (float)cold_days / all_days);
    }

    if (all_days == 0)
    {
    
    
        printf("没有数据输入!\n");
    }

    return 0;
}

result:

输入每日的最低温度列表:(q退出)
12 12 -1 12 12 12 -1 -1 12 12 q
一共 10 天,其中 30.0% 天都是极冷的。

while循环的测试条件是scanf() 的返回值,当读到非数字字符时会返回0,同时将其放入缓冲区,等待下一次读取。temperature 的类型是float 不是 int,这样的程序可以接受像-2.5这样的值,也可以接受8这样的值,会被自动转换为float。
使用强制类型转换可以明确表达式转换类型的意图,保护被编译器的影响,虽然可以自动转换,但是还是使用强制转换来提醒。

7.2 if else语句

  • getchar() 函数不带任何参数,它从输入队列中返回下一个字符。以下两种写法相同。

    ch =  getchar();
    scanf("%c",&ch);
    

    putchar() 打印字符同理:

    putchar(ch);
    printf("%c",ch);
    

    由于这两个函数只是处理字符,所以比通用的scanf和printf速度更快,更简洁,

    // cypher1.c -- 更改输入,空格不变,非空格替换成ASCII的下一个字符
    #include <stdio.h>
    #define SPACE ' '
    int main(int argc, char const *argv[])
    {
          
          
        char ch;
    
        ch = getchar();
        while (ch != '\n')
        {
          
          
            /* code */
            if (ch == SPACE)
            {
          
          
                putchar(ch);
            }
            else
            {
          
          
                putchar(ch + 1);
            }
            ch = getchar();
        }
        putchar('\n');
    
        return 0;
    }
    
    

    result:

    aaa bbb ccc
    bbb ccc ddd
    

    以上的循环可以替换成:

    while(ch=getchar() != '\n'){
          
          
    
    }
    

    ctype.h 头文件可以判断字符和数字。

    // cypher2.c -- 替换字母,非字母字符不变
    #include<stdio.h>
    #include<ctype.h>
    int main(int argc, char const *argv[])
    {
          
          
        char ch;
        while ((ch = getchar()) != '\n')
        {
          
          
            /* code */
            if(isalpha(ch)){
          
          
                putchar(ch+1);
            }else
            {
          
          
                putchar(ch);
            }
            
        }
        putchar(ch);
        
        return 0;
    }
    
    

    result:

    Look,it's a
    Mppl,ju't b
    

    注意判断条件一定是 while ((ch = getchar()) != ‘\n’) 要带括号。因为 != 的优先级高。

    // divisors.c -- 使用嵌套if语句显示一个数的约数
    #include <stdio.h>
    #include <stdbool.h>
    int main(int argc, char const *argv[])
    {
          
          
        unsigned long num;
        unsigned long div;
        bool isPrime; // flag 标记 素数标志
    
        printf("输入一个数:q退出\n");
        while (scanf("%lu", &num) == 1)
        {
          
          
            /* code */
            for (div = 2, isPrime = true; (div * div) <= num; div++)
            {
          
          
                if (num % div == 0)
                {
          
          
                    if ((div * div) % num != 0)
                    {
          
           // 不是完全平方数
                        printf("%lu 可以被 %lu 和 %lu 整除\n", num, div, num / div);
                    }
                    else
                    {
          
          
                        printf("%lu 是完全平方数被 %lu 整除\n", num, div);
                    }
                    isPrime = false;
                }
            }
            if (isPrime)
            {
          
          
                printf("%lu 是素数!\n", num);
            }
            printf("输入一个数:q退出\n");
        }
        printf("886");
    
        return 0;
    }
    
    

    result:

    输入一个数:q退出
    123456789
    123456789 可以被 3 和 41152263 整除
    123456789 可以被 9 和 13717421 整除
    123456789 可以被 3607 和 34227 整除
    123456789 可以被 3803 和 32463 整除
    123456789 可以被 10821 和 11409 整除
    输入一个数:q退出
    149
    149 是素数!
    输入一个数:q退出
    2013
    2013 可以被 3 和 671 整除
    2013 可以被 11 和 183 整除
    2013 可以被 33 和 61 整除
    输入一个数:q退出
    q
    886
    

7.3 逻辑运算符

&& 与 || 或 !非 ,引入 iso646.h 头文件可以 and or not 代替

// chcount.c -- 使用逻辑与运算符
#include<stdio.h>
#include <stdbool.h>
#define PERIOD '.'
int main(int argc, char const *argv[])
{
    
    
    char ch;
    int charcount = 0;
    while ((ch = getchar() != PERIOD))
    {
    
    
        /* code */
        if(ch!='"'&&ch!='\''){
    
    
            charcount++;
        }
    }
    printf("这里有 %d 个字符.\n",charcount);

    return 0;
}

result:

中文二字符abcd.
这里有 14 个字符.

7.4 一个统计单词的程序

// wordcnt.c -- 统计字符数,单词数,行数
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#define STOP '|'
int main(int argc, char const *argv[])
{
    
    
    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("输入文本以|结束:\n");
    prev = '\n';
    while ((c = getchar()) != STOP)
    {
    
    
        /* code */
        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("字符数 = %ld,单词数 = %d ,行数 = %d, ",n_chars,n_words,n_lines);
    printf("不完整的行数为 %d\n",p_lines);

    return 0;
}

result:

输入文本以|结束:
Reasin is a
powerful servant but
an inadequate master.
|
字符数 = 55,单词数 = 9 ,行数 = 3, 不完整的行数为 0

--------------------------------------------------
输入文本以|结束:
123|
字符数 = 3,单词数 = 1 ,行数 = 0, 不完整的行数为 1

7.5 条件运算符:?:

带一个运算对象的称为一元运算符,两个就是二元运算符,3个运算对象的就叫三元运算符。问号语句也叫三元运算符。

// paint.c -- 使用条件运算符
#include <stdio.h>
#define COVERAGE 350 // 每一罐油漆可以刷的面积
int main(int argc, char const *argv[])
{
    
    
    int sq_feet;
    int cans;
    printf("输入面积:q退出\n");
    while (scanf("%d", &sq_feet) == 1)
    {
    
    
        /* code */
        cans = sq_feet / COVERAGE;
        cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1;
        printf("你需要 %d %s 来刷!\n", cans, cans == 1 ? "can" : "cans");
        printf("输入面积:q退出\n");
    }

    return 0;
}

result:

输入面积:q退出
349
你需要 1 can 来刷!
输入面积:q退出
351
你需要 2 cans 来刷!
输入面积:q退出
q

7.6 循环辅助:continue 和 break

continue 跳过当前循环的剩余部分,进入下一次循环;break 终止当前层次的循环。

// skippart.c -- 使用continue跳过部分循环
#include <stdio.h>
int main(int argc, char const *argv[])
{
    
    
    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("输入第一个分数(q退出):\n");
    while (scanf("%f", &score) == 1)
    {
    
    
        /* code */
        if (score < MIN || score > MAX)
        {
    
    
            printf("%0.1f 是一个非法的值,重新输入:", score);
            continue;
        }
        printf("接收:%0.1f:\n", score);
        min = (score < min) ? score : min;
        max = (score > max) ? score : max;
        total += score;
        n++;
        printf("输入第一个分数(q退出):\n");
    }
    if (n > 0)
    {
    
    
        printf("一共 %d 个分数的平均分是 %0.1f.\n", n, total / n);
        printf("最小值 = %0.1f,最大值 = %0.1f\n", min, max);
    }
    else
    {
    
    
        printf("无效的分数!\n");
    }

    return 0;
}

result:

输入第一个分数(q退出):
1
接收:1.0:
输入第一个分数(q退出):
2
接收:2.0:
输入第一个分数(q退出):
3
接收:3.0:
输入第一个分数(q退出):
q
一共 3 个分数的平均分是 2.0.
最小值 = 1.0,最大值 = 3.0

--------------------------
输入第一个分数(q退出):
188
188.0 是一个非法的值,重新输入:12
接收:12.0:
输入第一个分数(q退出):
32
接收:32.0:
输入第一个分数(q退出):
q
一共 2 个分数的平均分是 22.0.
最小值 = 12.0,最大值 = 32.0

使用continue为了使代码逻辑简洁,有时也可以增加代码可读性。

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

break 语句对switch语句很重要

7.7 多重选择:swtich和break

image-20201022141440667

image-20201022141531663

7.8 goto语句

让它爬。

入第一个分数(q退出):
q
一共 3 个分数的平均分是 2.0.
最小值 = 1.0,最大值 = 3.0


输入第一个分数(q退出):
188
188.0 是一个非法的值,重新输入:12
接收:12.0:
输入第一个分数(q退出):
32
接收:32.0:
输入第一个分数(q退出):
q
一共 2 个分数的平均分是 22.0.
最小值 = 12.0,最大值 = 32.0


使用continue为了使代码逻辑简洁,有时也可以增加代码可读性。

```c
while(getchar()!='\n'){
	continue;
}

break 语句对switch语句很重要

7.7 多重选择:swtich和break

[外链图片转存中…(img-yqfGRyXt-1616425949909)]

[外链图片转存中…(img-TlvH7YFV-1616425949911)]

7.8 goto语句

让它爬。

猜你喜欢

转载自blog.csdn.net/qq_44880154/article/details/115104780