C语言修行中(2)学习了分支和循环结构

目录

顺序流程

分支流程

if关键词

else关键词

嵌套if

else if语句

条件运算符

条件表达式的优先级

循环结构

while循环

for循环

do while循环

循环嵌套

循环辅助

break关键词

continue关键词

while使用continue:

for使用continue

for使用break

总结

break和continue嵌套

多重选择语句switch


在C语言中,一个完整的程序包含三个代码控制流程:

顺序流程

分支流程

循环流程

顺序流程

按照书写的先后顺序,从前到后即从上到下执行的结构。

分支流程

如果满足一个条件(2到10之间)则走向一个流程,否则就走向另一个流程。这个流程属于分支流程。

if关键词


if(测试条件)

条件为真的流程


现在,提出一个新需求:

要求输入一个整数,如果数值在2到10之间,那么输出yes;否则什么也不做。

 int x;
 scanf_s("%d", &x);
 if (2 <= x && x <= 10)
 {
     printf("yes");
 }

else关键词


if(测试条件)

条件为真的流程

else

条件为假所执行的流程


现在有需求:

要求输入一个整数,如果数值在2到10之间,那么输出yes;否则输出no。

 int x;
 scanf_s("%d", &x);
 if (2 <= x && x <= 10)
 {
     printf("yes");
 }
 else
 {
     printf("no");
 }

if和else关键词只对它后面的一条语句产生效果,并且if和else之间只允许有一条语句。

如果想要执行多条语句,则使用大括号{},形成复合语句。

嵌套if

现有需求:

要求输入一个整数,如果小于2,则输出left;如果在2到10之间,则输出in;如果大于10,则输出right。

     int x;
     scanf_s("%d", &x);
     if (x < 2)
     {
         printf("left");
     }
     else
     {
         if (x > 10)
         {
             printf("right");
         }
         else
         {
             printf("in");
         }
     }

但是,如果将代码改成

 int x;
 scanf_s("%d", &x);
 if (x < 2)
 {
     printf("left");
 }
 if (2 <= x && x <= 10)
 {
     printf("in");
 }
 if (x > 10)
 {
     printf("right");
 }

如此,无论x的值满足哪个条件,都必须经过三个if语句的逻辑判断,虽然结果上是没有变化的,但是,如果x已经满足小于2这个条件,则完全没有必要继续测试后面的条件了,这样做会增加性能的消耗

else if语句

即省略大括号。

现有需求:

输入一个学生的分数x。

x<60,输出不及格;60<x<70,输出及格;70<x<80,输出一般;80<x<90,输出良好;90<x<100,输出优秀。

 int x;
 scanf_s("%d", &x);
 if (x < 60)
 {
     printf("不及格");
 }
 else if (60<=x&&x<70)
 {
     printf("及格");
 }
 else if (70 <= x && x < 80)
 {
     printf("一般");
 }
 else if (80 <= x && x < 90)
 {
     printf("良好");
 }
 else if (90 <= x && x <= 100)
 {
     printf("优秀");
 }

条件运算符

C语言中提供了一种条件表达式,作为if,else语句的一种便捷形式。是C语言中唯一一个三元运算符。


测试条件?表达式1:表达式2;

如果测试条件为真,则表达式1的结果是整个条件表达式的结果;反之,是表达式2的结果。


如果x>=10,则c为Y,反之c则为N:

 int x;
 char c;
 if (x >= 10)
 {
     c = 'Y';
 }
 else
 {
     c = 'N';
 }

运用条件运算符,可以写作

 int x;
 char c;
 c = x >= 10 ? 'Y' : 'N';

条件表达式的优先级

标记操作符类型优先级
++--自增、自减后缀16
++--自增、自减前缀15
!逻辑非单目15
+ -正、负号单目15
* / %乘、除、取余双目13
+ -加、减双目12
< > <= >=关系双目10
== !=相等、不相等双目9
&&逻辑与双目5
||逻辑或双目4
?:条件三目3
=赋值双目2

循环结构

while循环


while(循环条件)

循环行为


(高斯求和)现有需求:计算1+2+3+……+99+100最后的值等于多少

 int i = 1, sum = 0;
 //sum:用于存放每一次累加结果
 //i:表示逐个递增的整数
 while (i <= 100)
 {
     sum = sum + i;
     i++;
 }

在C语言中,非0即为真。

将while()括号里的内容改为0或其他数,0代表假,1(与其他数)代表真。

例如,while(1)将一直循环。

如何保证正确地、有限次数的循环

开始时,为计数器设置初始值

计数器与一个有限值比较,作为循环条件

更新计数器

for循环


for(计数器设置初始值;循环条件;计数器更新)

循环行为


使用for循环,可以将高斯求和写成

 int i, sum = 0;
 for (i = 1; i <= 100; i++)
 {
     sum = sum + i;
 }

代码中,for循环中的计数器,设置初始值仅仅在开始时执行一次,将i赋值为1。

循环条件成立,立即进入循环,否则将结束循环。

运行完一次循环行为后,将进行计数器更新,然后再次判断循环条件是否成立。

如果i仅作为计数器使用,并在循环结束后不关心i的值,则可以把i放在计数器初始化时声明,写成

 int sum = 0;
 for (int i = 1; i <= 100; i++)
 {
     sum = sum + i;
 }

这样i仅在循环体内有效,结束循环后失效。

可以试着用for打印100以内的所有偶数:

 for (int a = 0; a <= 100; a=a+2)
 {
     printf("%d ", a);
 }

for循环括号内的三个部分可以写到其他地方,或都可以为空。

例如

(1)计数器初始化为空

 int a = 0;
 for ( ;a <= 100; a = a + 2)
 {
     printf("%d ", a);
 }

(2)可以把计数器更新的部分写到循环里面

 int a = 0;
 for ( ;a <= 100; )
 {
     printf("%d ", a);
     a = a + 2;

(3)循环条件也可以为空,但是这将导致死循环

do while循环


do

循环行为

while(循环条件);


如果要输入一个数,这个数若不是整数或者零,就一直输入,直到输入了整数或者零为止。

 int x;
 do
 {
     scanf_s("%d", &x);
 } while (x < 0);

do while循环和while循环的差别是——

while进入循环前先检查循环条件是否满足,如果不满足,则一次都不执行。

do while先进行一次循环,再检查循环条件。所以至少会执行一次循环。

循环嵌套

 for (char c = 'A'; c <= 'E'; c++)
 {
     for (int i = 0; i <= 9; i++)
     {
         printf("%c%d ", c,i);
     }
     printf("\n");
 }

代码中,一个for循环嵌套另一个for循环。外层循环是从字母“A”到“E”,内层循环是从数字0到9。

运行之后,外层循环计数器初始值为A,进入循环后将开始内层循环,从0到9,打印的结果为A0到A9。内层循环执行完毕,输出"\n",外层循环计数器更新为B,再次重复上述的过程。

循环辅助

break关键词

作用:结束循环

 int i = 0;
 while (1)
 {
     if (i == 10)
     {
         break;
     }
     printf("%d", i);
     i++;
 }
 printf("\ni=%d", i);

break以后的语句均不执行。

现有需求:要求用户刷入一个密码,如果密码不为123456,那么输出密码错误;如果输入正确,则输出登陆成功。

 int password;
 while (1)
 {
     scanf_s("%d", &password);
     if (password == 123456)
     {
         break;
     }
     printf("密码错误\n");
 }
 printf("登陆成功\n");

continue关键词

作用:跳过本次循环,直接进入下一轮循环

while使用continue:

 int i = 0;
 while (i<20)
 {
     if (i == 6)
     {
         i = 12;
         continue;
     }
     printf("%d ", i);
     i++;
 }
 ​
 结果为
 0 1 2 3 4 5 12 13 14 15 16 17 18 19

for使用continue

 for (int i = 0; i < 20; i++)
 {
     if (i == 6)
     {
         i = 12;
         continue;
     }
     printf("%d ", i);
 }
 ​
 结果为
 0 1 2 3 4 5 13 14 15 16 17 18 19

两次的结果有一出不同,这是因为对于for循环,每次循环结束,都会执行一次for循环括号内的第三个表达式

所以continue之后先执行i++,再进行新一轮循环。

for使用break

 int i = 0;
 for (i = 0; i < 20; i++)
 {
     if (i == 6)
     {
         i = 12;
         break;
     }
     printf("%d ", i);
 }printf("\ni=%d", i);
 ​
 结果为
 0 1 2 3 4 5
 i=12

使用break后直接跳出循环,没有更新计数器。

总结

for中使用continue,将立即更新计数器,再进入新循环;

for中使用break,将直接跳出循环,不会更新计数器。

break和continue嵌套

作用于自己直属上层循环,例如break:

 for (;;)
 {
     for (;;)
     {
         break;//内层循环调用break,跳到外层循环
     }//                                 ↓
     break;//外层循环再次调用break,      ←
 }//         结束外层循环

多重选择语句switch


switch(整形表达式)

{

case 整形常量1:

语句

case 整形常量2:

语句

case 整形常量3:

语句

default:

语句

}


现有一个自动问答机器人,需要写出程序使得它会根据用户提出的问题回复对应的句子的,便可以使用switch语句:

 printf("请根据屏幕上的提示进行操作。\n");
 int 问题;
 scanf_s("%d", &问题);
 switch (问题)
 {
 case 1:
     printf("您提问:今天周几?\n");
     printf("小C真诚地回答您:今天周日,暂不工作,将在5s后关机,谢谢配合。\n");
     break;
 case 2:
     printf("您提问:吃了吗?\n");
     printf("小C真诚地回答您:谢邀,机在维修中心,刚喝汽油。\n");
     break;
 case 3:
     printf("您提问:我可以拿走这个吗?\n");
     printf("小C真诚地回答您:不可以呢亲,请先去XX窗口办理相关凭证。为您估算排队时间...预计一个小时。\n");
     break;
 default://如果输入不符合以上任一情况,则
     printf("小C迷惑地回答您:小C听不懂您在说什么呢,请根据提示使用智能小C问答机器——扣1或2或3呢亲。\n");
 }

如果case末没有加上break,则程序会把下面语句全部执行。当switch语句运行时遇到break关键字时会跳出,接下来剩下的case语句也不会再执行,switch语句结束。

而switch语句中的break只属于前者,效果只对其有效。(continue不对witch语句产生影响)

假如今天不是周日,智能问答机器小C不会在回答完一句后关机,而是继续服务,则可以写成

 printf("请根据屏幕上的提示进行操作。\n");
 int 问题;
 while (1)
 {
     scanf_s("%d", &问题);
     switch (问题)
     {
     case 1:
         printf("您提问:今天周几?\n");
         printf("小C热情地回答您:今天周一,小C将燃尽全油为您服务,请问您有什么问题?\n\n");
         break;
     case 2:
         printf("您提问:吃了吗?\n");
         printf("小C猝不及防地回答您:嗝...\n\n");
         break;
     case 3:
         printf("您提问:我可以拿走这个吗?\n");
         printf("小C大方地回答您:拿,都可以拿。\n\n");
         break;
     default:
         printf("小C迷惑地回答您:小C听不懂您在说什么呢,请根据提示使用智能小C问答机器——扣1或2或3呢亲。\n\n");
     }
 }

总结:学会了分支和循环后,感觉在C语言的学习上进了一大步,但是仍然有不足之处,希望能在后面的学习中不断精进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值