zoukankan      html  css  js  c++  java
  • 【零基础学习iOS开发】【02-C语言】09-流程控制

    前言

    1.默认的运行流程

    默认情况下,程序的运行流程是这样的:运行程序后,系统会按书写顺序执行程序中的每一行代码。比如下面的程序

    复制代码
     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     
     6     printf("Hello-1
    ");
     7     printf("Hello-2
    ");
     8     printf("Hello-3
    ");
     9     
    10     return 0;
    11 }
    复制代码

    程序运行后,会按顺序执行第6、7、8行语句,于是输出结果为:

    2.其他运行流程

    但很多时候,我们并不想要按照默认的运行流程去走,比如想在某个条件成立的情况下才执行某一段代码,否则不执行。比如微信的这个界面:

    如果用户点击了注册按钮,我们就执行“跳转到注册界面”的代码;如果用户点击了登录按钮,我们就执行“跳转到登录界面”的代码。如果用户没做出任何操作,就不执行前面所说的两段代码。要想实现这种功能,那就要学会如何去控制程序的运行流程。

    3.流程结构

    为了方便我们控制程序的运行流程,C语言提供3种流程结构,不同的流程结构可以实现不同的运行流程。这3种流程结构分别是:

    • 顺序结构:默认的流程结构。按照书写顺序执行每一条语句。
    • 选择结构:对给定的条件进行判断,再根据判断结果来决定执行哪一段代码。
    • 循环结构:在给定条件成立的情况下,反复执行某一段代码。

    下面是这3种结构的流程图,大致预览一下即可

    一、顺序结构

    顺序结构是3种结构中最简单的,也是默认的流程结构:程序中的语句是按照书写顺序执行的。在文章开头开始列出的代码段,就是顺序结构,这里就不多介绍了。

    二、选择结构1-if语句

    C语言中选择结构的实现方式有两种:if语句和switch语句。先来看下if语句的使用,而if语句的形式是有好多种的。

    1.形式1

    先来看看if语句最简单的形式

    1> 简介

    复制代码
    1 if ( 条件 )
    2 {
    3     语句1;
    4     语句2;
    5     ....
    6 }
    复制代码

    如果if右边小括号()中的条件成立,也就是为“真”时,就会执行第2~6行大括号{}中的语句;如果条件为假,就不执行大括号{}中的语句。这里的if是关键字。

    2> 举例

    复制代码
    1 int a = 7;
    2 
    3 if ( a )
    4 {
    5     printf("条件a成立
    ");
    6     printf("a的值为真");
    7 }
    复制代码

    C语言规定所有非0值都为“真”,而a的值是7,因此第3行的条件是成立的,接着就会执行第5、6行代码。输出结果如下:

    1 条件a成立
    2 a的值为真

    如果将a的值改为0,那么第3行的条件就不成立,就不会执行第5、6行代码

    3> 省略大括号{}

    如果if后面大括号{}中只有一行代码时,可以省略大括号。形式如下:

    if ( 条件 )
        语句1;

    注意:如果条件成立,只会执行if后面的第1条语句;如果条件不成立,就不会执行if后面的第1条语句。

    1 int a = 7;
    2 
    3 if ( a > 9 )
    4     printf("aaa");
    5     printf("bbb");

    因为第3行的a>9是不成立的,所以不会执行第4行代码。而第5行代码跟if语句是没有任何练习的,因此,第5行代码照常执行。于是会看到屏幕上只输出:

    由于第5行代码跟if语句是没有任何联系的,所以一般会把代码写成下面这样:

    1 int a = 7;
    2 
    3 if ( a > 9 )
    4     printf("aaa");
    5 printf("bbb");

    为了保证代码的可读性,不建议省略大括号!!!

    4> 语句嵌套

    if语句内部是可以嵌套其他if语句的,如下面的例子

    复制代码
     1 int a = 7;
     2 
     3 if ( a > 0 )
     4 {
     5     printf("a的值大于0
    ");
     6     
     7     if ( a<9 )
     8     {
     9         printf("a的值小于9");
    10     }
    11 }
    复制代码

    第3行的a>0是成立的,因此会按顺序执行第4~11大括号中的代码。执行到第7行的时候,a<9也是成立的,因此会执行第9行代码。输出结果:

    1 a的值大于0
    2 a的值小于9

    5> 使用注意1

    有些人习惯写完一行代码就在后面加个分号";",于是写if语句的时候,他们可能会这样写:

    1 int a = 6;
    2 if ( a>8 );
    3 {
    4     printf("a大于8");
    5 }

    如果第2行尾部的分号,其实一个分号也是一条语句,这个叫做“空语句”。第2行的a>8不成立,所以不会执行后面的“空语句”。而后面的大括号{}跟if语句是没有联系的,因此会正常执行,于是会看到输出:

    a大于8

    所以要非常小心,千万不要在if的小括号后面添加分号。

    第3~5行的内容是一个独立的“代码块”:

    1 {
    2     printf("a大于8");
    3 }

    6> 使用注意2

    下面的写法从语法的角度看是对的:

    复制代码
    int a = 10;
    
    if (a = 0) {
        printf("条件成立");
    } else {
        printf("条件不成立");
    }
    复制代码

    上述代码是完全合理的,编译器不会报错,只是个警告而已。因为a为0,所以为"假",输出结果是:"条件不成立"

    这里隐藏着很大的陷阱在:

    假设你本来是想判断a是否为0,那么本应该写if (a == 0),若你误写成了if (a = 0),那将是一件非常可怕的事情,因为编译器又不报错,这样的BUG就难找了。因此,像a==0这样的表达式,最好写成0==a,若你误写成0=a,编译器会直接报错的。

    复制代码
    // 不推荐
    if (a == 0) {
    }
    
    // 推荐
    if (0 == a) {
    }
    复制代码

    7> 使用注意3

    在C语言中,可以不保存关系运算的结果。因此,下面的写法是合法的:

    1 int a = 10;
    2 a > 10;
    3 a == 0;

    这里又是一个陷阱,假设你的本意是想给a赋值为0,那么本应该写a = 0; ,若你误写成a == 0; ,那将又是一个非常难找的BUG,因为编译器根本不会报错。在1993年的时候,这个BUG差点让一桩价值2000万美元的硬件产品生意告吹,因为如果这个BUG不解决,这个产品就没办法正常使用

    2.形式2

    if还可以跟关键字else一起使用

    1> 简介

    复制代码
    1 if ( 条件 )
    2 {
    3     语句1;
    4 }
    5 else
    6 {
    7     语句2;
    8 }
    复制代码

    如果条件成立,就会执行if后面大括号{}中的语句;如果条件不成立,就会执行else后面大括号{}中的语句。总之,两个大括号中一定会有1个被执行,而且只能执行的1个。

    为了减少代码行数,你也可以写成下面的格式:

    1 if ( 条件 ) {
    2     语句1;
    3 } else {
    4     语句2;
    5 }

    当然,也可以省略大括号,写成下面的格式:

    1 if ( 条件 )
    2     语句1;
    3 else
    4     语句2;

    如果条件成立,就执行if后面的第1条语句;如果条件不成立,就执行else后面的第1条语句。但还是不建议省略大括号{}。

    2> 举例

    复制代码
    1 int a = 10;
    2 if ( a==0 ) {
    3     printf("a等于0");
    4 } else {
    5     printf("a不等于0");
    6 }
    复制代码

    第2行的a==0不成立,所以会执行第5行代码,输出结果:

    a不等于0

    3.形式3

    if和else还有一种比较复杂的用法

    1> 简介

    复制代码
     1 if ( 条件1 )
     2 {
     3     语句1;
     4 }
     5 else if ( 条件2 )
     6 {
     7     语句2;
     8 }
     9 else if ( 条件3 )
    10 {
    11     语句3;
    12 }
    13 ...
    14 else
    15 {
    16     其他语句;
    17 }
    复制代码
    • 如果条件1成立,就执行条件1后面大括号{}中的内容:第2~4行
    • 如果条件1不成立,条件2成立,就执行条件2后面大括号{}中的内容:第6~8行
    • 如果条件1、条件2都不成立,条件3成立,就执行条件3后面大括号{}中的内容:第10~12行
    • 第13行的...表示可以有无限个else if
    • 如果所有的条件都不成立,就会执行else后面大括号{}中的内容:第15~17行

    注意:这么多大括号中,只有1个大括号内的代码会被执行。跟之前一样,所有的大括号都可以省略,但是不建议省略。必要的时候,最后面的else那一段(第14~17行)是可以省略的。

    2> 举例

    复制代码
    1 int a = 10;
    2 if ( a==0 ) {
    3     printf("a等于0");
    4 } else if( a>0 ) {
    5     printf("a大于0");
    6 } else {
    7     printf("a小于0");
    8 }
    复制代码

    第2行中的a==0不成立,接着会检查第4行。第4行的a>0成立,因此会执行第5行代码。输出结果:

    a大于0

    如果a的值是负数,那么第2、4行的条件都不成立,于是就会执行第7行代码。

    三、选择结构2-switch语句

    1.形式

    先来看看switch语句的使用形式:

    复制代码
     1 switch(整型表达式)
     2 {
     3     case 数值1:
     4         语句1;
     5         break;
     6     case 数值2:
     7         语句2;
     8         break;
     9     ... ...
    10     case 数值n:
    11         语句n;
    12         break;
    13     default :
    14         语句n+1;
    15         break;
    16 }
    复制代码
    • 当整型表达式的值等于“数值1”时,就会执行“语句1”,后面的break表示退出整个switch语句,也就是直接跳到第16行代码;
    • 当整形表达式的值等于“数值2”时,就会执行“语句2”;后面的以此类推。如果在数值1~数值n中,没有一个值等于整型表达式的值,那么就会执行default中的语句n+1。
    • 由于所有的case后面都有个break,因此执行完任意一个case中的语句后,都会直接退出switch语句

    2.举例

    复制代码
     1 int a = 10;
     2 
     3 switch (a) {
     4     case 0:
     5         printf("这是一个0");
     6         break;
     7     case 5:
     8         printf("这是一个5");
     9         break;
    10     case 10:
    11         printf("这是一个10");
    12         break;
    13     default:
    14         printf("什么也不是");
    15         break;
    16 }
    复制代码

    因为a的值刚好等于第10行case后面的10,所以会执行第11行代码,输出结果:

    这是一个10

    3.break

    break关键字的作用是退出整个switch语句。默认的格式中,每个case后面都有个break,因此执行完case中的语句后,就会退出switch语句。

    1> 如果某个case后面没有break,意味着执行完这个case中的语句后,会按顺序执行后面所有case和default中的语句,直到遇到break为止

    复制代码
     1 int a = 0;
     2 
     3 switch (a) {
     4     case 0:
     5         printf("这是一个0
    ");
     6     case 5:
     7         printf("这是一个5
    ");
     8     case 10:
     9         printf("这是一个10
    ");
    10         break;
    11     default:
    12         printf("什么也不是
    ");
    13         break;
    14 }
    复制代码
    • 由于变量a的值等于第4行case后面的0,因此肯定会执行第5行代码。
    • 由于case 0中没有break语句,就不会退出switch语句,继续往下执行代码。
    • 由于a的值已经等于第4行case的值,接着不会再判断a的值是否等于其他case的值了,直接按顺序执行第7、9行代码。在第10行有个break,接着就会退出switch语句。
    • 输出结果为:
    1 这是一个0
    2 这是一个5
    3 这是一个10

    如果把a的值改为5,输出结果为:

    1 这是一个5
    2 这是一个10

    2> 在某些时候,我们确实没有必要在每一个case后面添加break。下面举一个例子:判断分数的优良中差等级(100分满分)。

    复制代码
     1 int score = 77;
     2 
     3 switch (score/10) {
     4     case 10:
     5     case 9:
     6         printf("优秀");
     7         break;
     8         
     9     case 8:
    10         printf("良好");
    11         break;
    12         
    13     case 7:
    14     case 6:
    15         printf("中等");
    16         break;
    17         
    18     default:
    19         printf("差劲");
    20         break;
    21 }
    复制代码
    • 当score的范围是90~100,score/10的值为10或9时,就会执行第6行代码,然后退出switch语句;
    • 当score的范围是80~89,score/10的值为8时,就会执行第10行代码,然后退出switch语句;
    • 当score的范围是60~79,score/10的值为7或6时,就会执行第15行代码,然后退出switch语句;
    • 当score的范围并不是60~100,score/10的值并不在6~10范围内时,就会执行第19行代码,然后退出switch语句;
    • score的值是77,所以score/10的值是7,输出结果:中等

    4.在case中定义变量

    有时候,我们可能会想在case中定义一些变量,这个时候,就必须用大括号{}括住case中的所有语句。

    复制代码
     1 int a = 10;
     2 int b = 4;
     3 
     4 char op = '-';
     5 
     6 switch (op)
     7 {
     8     case '+':
     9     {
    10         int sum = a + b;
    11         printf("a+b=%d
    ", sum);
    12         break;
    13     }
    14         
    15     case '-':
    16     {
    17         int minus = a - b;
    18         printf("a-b=%d
    ", minus);
    19         break;
    20     }
    21         
    22     default:
    23         printf("不能识别的符号");
    24         break;
    25 }
    复制代码

    在第10、17分别定义两个变量。输出结果:

    a-b=6

    四、循环结构1-while循环

    假如要你在屏幕上重复输出10次Hello World,你会怎么做?简单,把下面的代码拷贝10份就行了。

    1 printf("Hello World
    ");

    没错,把上次代码写10遍,确实能实现功能。但是这样的代码太垃圾了,有很多的重复的代码,这样会使得代码非常地臃肿,复用率低。因此,不建议这么做。

    下次遇到像上面那样重复执行某个操作时,首先要想到的应该是循环结构。所谓循环,就是重复执行某一个操作,C语言中有多种方式可以实现循环结构。先来看看while循环。

    1.形式

    复制代码
    1 while ( 条件 )
    2 {
    3     语句1;
    4     语句2;
    5     ....
    6 }
    复制代码
    • 如果条件成立,就会执行循环体中的语句(“循环体”就是while后面大括号{}中的内容)。然后再次判断条件,重复上述过程,直到条件不成立就结束while循环
    • while循环的特点:如果while中的条件一开始就不成立,那么循环体中的语句永远不会被执行

    可以省略大括号{},但是只会影响到while后面的第一条语句。不建议省略大括号。

    1 while ( 条件 )
    2     语句1;

    2.举例

    在屏幕上重复输出10次Hello World,每输出一次的换行。

    复制代码
    1 int count = 0;
    2 while ( count < 10 )
    3 {
    4     printf("Hello World
    ");
    5    
    6     count++;
    7 }
    复制代码

    如果省略第6行的count++,count就一直是0,那么count<10一直都是成立的,这个while循环将会陷入“死循环”,一直在重复执行第4行代码。

    3.注意

    如果写成下面这样,也会让程序进入“死循环”

    复制代码
    1 int count = 0;
    2 
    3 while ( count < 10 );
    4 {
    5     printf("Hello World
    ");
    6     
    7     count++;
    8 }
    复制代码
    • 注意第3行,while后面不小心加了个分号; ,一个分号表示一条空语句。
    • 可以看出:while循环只会影响到第3行的空语句,而第4~8行的代码块是不受while循环影响的
    • 由于count是0,那么count<10一直都是成立的,程序将会一直重复执行第3行的空语句,陷入死循环。

    五、循环结构2-do while循环

    形式如下:

    1 do {
    2     语句1;
    3     语句2;
    4     ...
    5 } while (条件);
    • 注意第5行,后面是加上一个分号;的
    • 当执行到do-while循环时,首先会执行一遍循环体中的语句(“循环体”就是do后面大括号{}中的内容)。接着判断while中的条件,如果条件成立,就执行循环体中的语句。然后再次判断条件,重复上述过程,直到条件不成立就结束while循环
    • do-while循环的特点:不管while中的条件是否成立,循环体中的语句至少会被执行一遍
    • 其实do while循环的用法跟while循环是差不多的,这里就不举例子了。

    六、循环结构3-for循环

    1.形式

     for循环是所有循环结构中最复杂的。

    1 for (语句1; 条件; 语句2) {
    2     语句3;
    3     语句4;
    4     ...
    5 }
    • for循环开始时,会先执行语句1,而且在整个循环过程中只执行一次语句1
    • 接着判断条件,如果条件成立,就会执行循环体中的语句(“循环体”就是for后面大括号{}中的内容)
    • 循环体执行完毕后,接下来会执行语句2,然后再次判断条件,重复上述过程,直到条件不成立就结束for循环

    2.举例

    1 for (int i = 0; i<5; i++)
    2 {
    3     printf("%d  ", i);
    4 }

    输出结果为:

    0  1  2  3  4  

    需要注意的是:变量i的作用域是第1~4行。一旦离开了这个for循环,变量i就失效了。

    3.补充

    如果for循环的初始化语句和循环一次后执行的语句是由多条语句组成的,就用逗号,隔开

    1 for (int x = 0, y =0; x<3; x++, y+=2)
    2 {
    3     printf("x=%d, y=%d 
    ", x, y);
    4 }

    输出结果:

    x=0, y=0 
    x=1, y=2 
    x=2, y=4 

    七、break和continue

    接下来,介绍两个比较重要的语句:break和continue。

    1.break

    前面在switch语句中已经用到了break,它的作用是跳出switch语句。它也可以用在循环结构中,这时候它的作用是跳出整个循环语句。

    1> 举例

    这里以for循环为例子,break也可以用在while循环、do-while循环中。

    复制代码
    1 for (int i = 0; i<5; i++) {
    2     printf("i=%d 
    ", i);
    3     
    4     if (i>2) {
    5         break;
    6     }
    7 }
    复制代码

    上面代码的意思是当i>2时,就跳出整个for循环,也就是结束for循环,所以输出结果是:

    i=0 
    i=1 
    i=2 
    i=3 

    2> for循环嵌套

    先来看一个for循环嵌套的例子,嵌套的意思就是:for循环内部又一个for循环

    1 for (int x = 0; x<2; x++) {
    2     for (int y = 0; y<2; y++) {
    3         printf("x=%d, y=%d 
    ", x, y);
    4     }
    5 }

    输出结果是:

    1 x=0, y=0 
    2 x=0, y=1 
    3 x=1, y=0 
    4 x=1, y=1 

    这个时候如果在for循环中加入一个break,那么这个break究竟是跳出里面还是外面的for循环呢?

    复制代码
    1 for (int x = 0; x<2; x++) {
    2     for (int y = 0; y<2; y++) {
    3         printf("x=%d, y=%d 
    ", x, y);
    4         
    5         break;
    6     }
    7 }
    复制代码

    注意第5行的break,这个break的作用是跳出里面的for循环,并非外面的for循环。所以输出结果是:

    x=0, y=0 
    x=1, y=0 

    如果改变一下break的位置

    复制代码
    1 for (int x = 0; x<2; x++) {
    2     for (int y = 0; y<2; y++) {
    3         printf("x=%d, y=%d 
    ", x, y);
    4     }
    5     
    6     break;
    7 }
    复制代码

    注意第6行的break,这个break的作用是跳出外面的for循环,并非里面的for循环。所以输出结果是:

    x=0, y=0 
    x=0, y=1 
    
    

    规律已经很明显了:break只会影响它所在的那个for循环

    2.continue

    continue只能使用在循环结构中,它的作用是跳过这一次循环,直接进入下一次循环。

    这里以for循环为例子,continue也可以用在while循环、do-while循环中。

    复制代码
    1 for (int x = 0; x<10; x++) {
    2     if (x%2==0) {
    3         continue;
    4     }
    5     
    6     printf("x=%d 
    ", x);
    7 }
    复制代码

    注意第2行,当x%2==0,也就是当x是2的倍数时,就跳过这次循环,不执行第6行语句,直接进入下一次循环。输出结果:

    1 x=1 
    2 x=3 
    3 x=5 
    4 x=7 
    5 x=9 

    跟break一样,continue只会影响它所在的那个for循环

  • 相关阅读:
    node.js 安装后怎么打开 node.js 命令框
    thinkPHP5 where多条件查询
    网站title中的图标
    第一次写博客
    Solution to copy paste not working in Remote Desktop
    The operation could not be completed. (Microsoft.Dynamics.BusinessConnectorNet)
    The package failed to load due to error 0xC0011008
    VS2013常用快捷键
    微软Dynamics AX的三层架构
    怎样在TFS(Team Foundation Server)中链接团队项目
  • 原文地址:https://www.cnblogs.com/LiLihongqiang/p/5677777.html
Copyright © 2011-2022 走看看