分支和循环相关

似梦清欢
• 阅读 714

C语言中表示真假:0表示假,非0表示真。

分支语句:if、switch。循环语句:while、for、do while。


switch后跟整形表达式:

switch(整形表达式)
{
    case 整形常量表达式:
        语句; 
 }

switch语句搭配break实现语句分支(在每一个case后放上break跳出)。

::: tip 在需要匹配相同输出内容时,可以连续使用“case:”在最后一个case后使用break。 每个switch语句中都需要有一个默认输出的default子句,后面也可以加break。 switch语句中defaults子句的位置没有确切要求(习惯放在最后)。 ::: ::: warning break表示永久中止循环。 continue表示中止循环中本次循环continue后面的代码, 直接跳到循环判断部分进行下一次循环的入口判断。

#include <stdio.h>

int main()
{
    int i = 0;
    while(i <= 10)
    {
        if (i == 5)
            continue;
        printf("%d",i);
        i++;
    }
    return 0 ;
}

:::

if-else语句中,悬空else的匹配问题: else和距离最近的未匹配的if匹配,不和与之对齐的if匹配。


getchar和putchar getchar作用:输入一个字符(通常用于接受换行符以及空格)。 putchar作用:输出一个字符。

#include <stdio.h>

int main()
{
    int ret = 0;
    char password[20] = {0};
    printf("请输入密码:");
    scanf("%s",password);  //输入密码并存放在password数组中
    printf("请确认(N/Y)\n");
    ret = getchar();
    if (ret == 'Y')
    {
        printf("确认成功\n");
    }
    else
    { 
        printf("放弃确认\n");
    }
    return 0 ;
}
请输入密码:123456
请确认(N/Y)
放弃确认

--------------------------------
Process exited after 2.484 seconds with return value 0

上述代码输出结果时候,没有输入N/Y,直接输出“放弃确认”后结束程序。 在调试中,第8行scanf执行输入123456后,变量password数组加入了值123456;程序运行到11行if (ret == ‘Y’)时,ret的值变为10。 ::: tip

#include <stdio.h>

int main()
{
  printf("%d\n",'\n');
  return 0;
}
10

--------------------------------
Process exited after 0.01777 seconds with return value 0

由上可知,“\n”的值为10。 :::

之前的代码中ret=getchar()=10,即getchar读到了一个“\n”。ret != Y,执行else语句,输出“放弃确认”。 在程序中,scanf和getchar属于输入函数,在读取输入内容时会检测输入缓冲区,在第一次需要读入内容时,输入缓冲区为空,程序会等待输入,当输入完毕后,输入函数会从输入缓冲区内拿走需要的数据,在getchar需要读入数据时,也会去检测输入缓冲区,如果输入缓冲区有内容,会直接被getchar读走,如果没有,程序会等待输入。

#include <stdio.h>

int main()
{
        int ret = 0;
        char password[20] = {0};
        printf("请输入密码:");
        scanf("%s",password);
        //缓冲区剩余一个“\n”需要清空 
        getchar();
        printf("请确认(N/Y)\n");
        ret = getchar();
        if (ret == 'Y')
        {
            printf("确认成功\n");
        }
        else
        { 
            printf("放弃确认\n");
        }
        return 0 ;
}
请输入密码:123456
请确认(N/Y)
放弃确认

--------------------------------
Process exited after 3.49 seconds with return value 0

如上,在第一次输入密码“123456”后,回车使得scanf读到密码,即输入缓冲区内的内容是“1234546\n”,scanf读走了123456,剩下的“\n”被getchar读走。

#include <stdio.h>

int main()
{
        int ret = 0;
        char password[20] = {0};
        printf("请输入密码:");
        scanf("%s",password);
        //缓冲区剩余一个“\n”需要清空 
        getchar();
        printf("请确认(N/Y)\n");
        ret = getchar();
        if (ret == 'Y')
        {
            printf("确认成功\n");
        }
        else
        { 
            printf("放弃确认\n");
        }
        return 0 ;
}
请输入密码:123456
请确认(N/Y)
Y
确认成功

--------------------------------
Process exited after 6.671 seconds with return value 0

如上述代码的第10行,在scanf读取结束后,将缓冲区内剩余的内容用getchar读走,此处的getchar并不关心返回值,只是为了清空缓冲区,可以直接用“gatchar();”。输入缓冲区被清空后,第12行的getchar不能从缓冲区内读到内容,程序就会停下来等待输入。

::: warning 上述代码的缺陷是,如果输入缓冲区内的内容较多,一个getchar就不能完全清空。如下:

#include <stdio.h>

int main()
{
        int ret = 0;
        char password[20] = {0};
        printf("请输入密码:");
        scanf("%s",password);
        getchar();
        printf("请确认(N/Y)\n");
        ret = getchar();
        if (ret == 'Y')
        {
            printf("确认成功\n");
        }
        else
        { 
            printf("放弃确认\n");
        }
        return 0 ;
}
请输入密码:123456 ABCD
请确认(N/Y)
放弃确认

--------------------------------
Process exited after 6.08 seconds with return value 0

::: 上述代码执行错误的原因是,scanf读取到空格就会停止读入。第9行的getchar只能读到一个空格,第11行getchar读取时仍会从输入缓冲区内读入。


while循环流程图: 分支和循环相关 为了解决上述问题,需要写一个while循环,使得getchar不断读取输入缓冲区的内容,直到读取到第一次填充输入缓冲区后的回车“\n”。如下:

#include <stdio.h>

int main()
{
        int ret = 0;
        char password[20] = {0};
        printf("请输入密码:");
        scanf("%s",password);
        while(getchar() != '\n')
        {
            ;  //空语句,循环只需要不断从缓冲区内读取内容,不需要其他动作
        }
        printf("请确认(N/Y)\n");
        ret = getchar();
        if (ret == 'Y')
        {
            printf("确认成功\n");
        }
        else
        { 
            printf("放弃确认\n");
        }
        return 0 ;
}
请输入密码:123456 ABCD
请确认(N/Y)
Y
确认成功

--------------------------------
Process exited after 7.183 seconds with return value 0

for循环 for(表达式1;表达式2;表达式3) 循环语句; ::: tip 表达式1为初始化部分,用于初始化循环变量;表达式2为条件判断部分,用于判断循环是否终止;表达式3为调整部分,用于循环条件的调整。 执行顺序是表达式1-表达式2-循环语句-表达式3-表达式2。 :::

for循环执行流程图:分支和循环相关

for语句循控制变量: 1.不可在for循环体内修改循环变量,防止for循环失去控制。 如下:

#include <stdio.h>

int main()
{
    int i = 0;
    for(i = 0;i < 10;i++)
    {
        if(i = 5)
            printf("haha\n");
        printf("hehe\n");
    }
    return 0;
}

上述代码第8行if语句内是赋值语句,在for循环内,设置了变量i的调整语句,使得每次进入循环后,变量i的值都被赋值成5,出现死循环。 2.建议for语句的循环控制变量的取值采用“前闭后开区间”写法。 如下:

#include <stdio.h>

int main()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    int i = 0;
    for(i = 0;i < 10;i++)
    {
        printf("%d ",a[i]);
    }
    return 0;
}

上述代码第7行的条件判断语句,写成前闭后开的写法i<10,不会写成i<=9。 ::: tip 不是所有的循环控制语句都写成前闭后开,具体情况具体分析。 :::

for循环的变种: 1.for循环的初始化、调整、判断都可以省略。如果省略for循环的判断部分,即判断结果恒为真,会陷入死循环:

#include <stdio.h>

int main()
{
    for(;;)
    {
        printf("emmm\n");
    }
    return 0;
}

2.for循环中不能随意省略语句: 分支和循环相关 上图左边代码因为for循环中初始化值和定义变量的值相同,省去了初始化的语句,在代码执行结果中出现了和原结果不同的结果。 ::: warning 在上述右侧省去初始化语句的代码中,进入第一个for循环时,i=0,符合判断条件,进入内层循环,j从0增加到3,打印3次结果,此时j=3,不满足判断条件,跳出内层循环;i++变为1,符合判断条件,进入内层循环,j=0的初始化语句不存在,j的值为上次跳出循环的值,j=3,不满足条件,跳出内层循环;i++变为2…i++变为3,不满足条件,跳出循环,结束,整个程序运行过程中只有i=0,j=0、1、2时打印结果,即打印出3个结果。 :::

::: tip 面试题:

#include <stdio.h>

int main()
{
    int i = 0;
    int j = 0;
    for(i = 0,j = 0;j = 0;i++,j++)
    {
        j++;
    }
    return 0;
}

--------------------------------
Process exited after 0.01387 seconds with return value 0

上述代码中第7行j=0的位置应该是一条判断语句,但写成了赋值语句,把0赋给j,表达式的结果是j的值即为0,0表示假,判断结果为假,不满足条件,不进入循环。 (如果这个语句是j赋值非0,就是死循环)。 :::

do-while语句执行流程图: 分支和循环相关

点赞
收藏
评论区
推荐文章

暂无数据

似梦清欢
似梦清欢
Lv1
学海无涯
文章
17
粉丝
17
获赞
1