前言:
本篇为你讲解分支语句和循环语句的使用,把分支与循环清晰化。
分支和循环语句篇:
一、语句
c语言是结构化的程序语言。c语言中有三种结构:
- 顺序结构(从头到底)
- 选择结构(if、switch)
- 循环结构(while、for、do…while)
那什么是语句?
在c语言中规定,在写完一条语句的时候在后面加上分号;
就是一条语句,也就是说C语言中由一个分号 ; 隔开的就是一条语句。
比如:
int main()
{
int a = 5;//这就是一条语句
printf("%d", a);//这也是一条语句
;//这还是语句,这是空语句
return 0;
}
二、分支语句
1.分支语句(选择结构)
什么是分支呢,就是从总体或一个系统中分出部分,而选择结构,就是你进行了某种操作之后从而得到不一样的结果。
比如说你考上了大学,如果你好好学习,那么在毕业就可以拿到好offer;如果你不好好学习,那你毕业之后就老老实实回家养猪了。
这样子:
又或者是:
2.if语句
if语句就是用来判断某件事情是否成立,如果成立则执行以下操作,它还可以搭配else,else if进行组合,从而将几种判断可能都可以表示。
if语句的语法结构:
1. if(表达式)
语句;
2. if(表达式)
语句1;
else
语句2;
3. if(表达式1)//多分支
语句1;
else if(表达式2)
语句2;
else
语句3;
第一种就是最基本的if语句:
基础判断一件事情是否真假,实际上,if语句中表达式真正决定的是表达式的值,比如下面的money >= price
,如果成立,那表达式值为1,如果不成立,表达式值为0。在c语言中,0表示假,非0表示真,但真的事件转换为数字时是默认转换为1。
int main()
{
int price = 39;//价格
int money = 50;//余额
if (money >= price)//判断余额是否大于价格
{
printf("余额充足,可以购买!");//如果成立,就输出这个语句
}
return 0;
}
第二种是可以进行分支的if else语句:
if else语句就像它英语释义一样,如果…其他,就是if语句判断某种事情的一种结果,然后其他结果的执行else语句。
int main()
{
int age = 18;
if (age >= 18)//大于等于18则表达式为1
{
printf("您已成年");
}
else//除了上面的可能其余结果均是未成年
{
printf("您未成年");
}
return 0;
}
第三种if else if else语句:
if else if else就是前面两个的组合体,可以判断多种可能和其余可能,实现多个分支选择。
int main()
{
float rec = 12.91;//奥运会110米栏奥运会记录
float your_ach = 13.22;//奥运成绩
if(your_ach<rec)//判断成绩是否比奥运会记录小
{
printf("你的成绩打破了奥运会记录!\n");
}
if (your_ach <= 13.02)//拿金牌的成绩
{
printf("恭喜你,获得金牌!");
}
else if (your_ach <= 13.20 && your_ach > rec)//前三名成绩范围
{
printf("恭喜你,获得奖牌!");
}
else//其他成绩
{
printf("很遗憾,未能获得奖牌,但已经很棒了!");
}
return 0;
}
这里需要注意:
if…else if语句中,如果if判断为真,则不会再执行判断else语句,两者是二选一关系,而if为假才会再去判断else里面的if语句。
<>
而if…if…语句的话,则是按顺序执行,执行完上面的if语句,无论真假,继续执行下面的if语句。
还有些代码可能是这样子的:
int main()
{
int a = 5;
if (a > 10)
{
printf("yes");
}
else
printf("no");//加个{ }更好
}
int main()
{
int a = 15;
if (a > 10)
printf("yes");
return 0;//加上else { }更好
}
这些代码也可以运行,但是整体不够美观,在这些代码的基础上加上花括号对称显示,这样逻辑更加清晰,不容易出错。
比如下面代码就让人容易以为打印的是1:
int main()
{
int a = 1;
int b = 2;
if (a == 0)
if (b == 2)
printf("1");
else
printf("0");
return 0;
}
最后,了解了if语句之后是不是就可以把一开始的分支的流程图写出来了?
int main()
{
char ch = 0;
printf("你上大学了,是否想好好学习?");
printf("请输入Y/N:>\n");
scanf("%c", &ch);
if (ch == 'Y')
{
printf("我要好好学习!\n");
printf("三年后...\n");
printf("你拿到了好offer!\n");
}
else if (ch == 'N')
{
printf("我不想好好学习\n");
printf("三年后...\n");
int a = 0;
printf("家大业大/普通人:1/2:>\n");
scanf("%d", &a);
if (a == 1)
{
printf("你还是拿到了offer\n");
}
else if (a == 2)
{
printf("回家养猪去吧\n");
}
}
return 0;
}
3.switch语句
接下来到我们的switch语句,switch语句也是一种分支语句。 常常用于多分支的情况。
有了if分支还又多一个switch干嘛,下面用一个代码来进行说明:
//假设我要打印今天是星期几
int main()
{
int day = 0;
scanf("%d", &day);
if (day == 1)
{
printf("今天是星期一");
}
else if (day == 2)
{
printf("今天是星期二");
}
else if (day == 3)
{
printf("今天是星期三");
}
//..........还要写几个
return 0;
}
这样子是不是代码有点拖泥带水呢,那这时候就应该使用switch了:
switch语句的语法结构:
switch(整形表达式)
{
case 整形常量表达式:
语句;
}
//附带产品:
break;
//跳出,当执行完某个语句后,跳出整个循环
default
//分支中没有switch整形表达式,执行default子句
用switch语句就可以更清晰简单的多分支:
int main()
{
int day = 0;//整形
scanf("%d", &day);
switch(day)//day必须是整形表达式
{
case 1:
//case入口也需要是整形常量表达式
printf("星期一\n");
break;//跳出
//case就好像分支入口,而break就是分支出口
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期天\n");
break;
default:
printf("输入有误,无法识别");
//当输入的数字不是1-7的时候执行这个语句
}
return 0;
}
在上面的代码中,swicth(day)
就相当于非诚勿扰的择偶要求,如果day是1,那我就去case 1那里,然后执行case 1里面的内容。如果是2,那么就选择去了case 2那里。而break相当于出口,就是执行完case 1的内容就跳出去了,如果case 1最后没有break,那他就会自动执行下去case 2。但不是所有的switch语句都用上break,这要看代码的逻辑。
比如我想知道今天需不需要上课:
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("今天是上学日,加油上学人!\n");
break;
case 6:
case 7:
printf("今天是休息日,要好好休息哦!\n");
break;
default:
printf("输入有误,无法识别\n");
break;
}
注意:
if ,switch语句都可以进行嵌套,可以在分支进入之后再分支,完成更复杂的判断。switch语句中,在最后一个 case 语句的后面加上一条 break语句。之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句。
三、循环语句
1.循环
但我们认识上面的选择语句中,我们来认识循环语句。if语句中,当条件满足的情况下,if语句后的语句执行,否则不执行。但是这个语句只会执行一次。那我们需要多次判断呢?就需要我们的循环语句了。
2.while语句
while 语句语法结构:
while(表达式)
循环语句;
//附赠
continue;
//用于终止本次循环的,也就是continue后的代码在本次不在执行下去
while语句中,表达式结果为真,就进入循环,执行一次,再回来判断表达式结果,如果表达式为1,那么代码将进入无限循环。
比如:
那么他将进入疯狂点赞我的行为当中且无法自拔。
言归正传,那while语句什么时候使用呢? 比如你要打印1到10的数字的时候,总不能说printf()
上10个吧,那10000个数的时候呢?所以在一件事情没有完成之前都继续执行下去,我们就可以用while语句:
int main()
{
int count = 1;
while (count<10)
{
printf("我真帅!第%d次呼喊\n",count);
count++;
}
return 0;
}
这里怎么才呼喊9次啊,我们要看到我们的条件表达式上写的是count<10,所以当count加到10那一次,我就不再进去了。因为while语句是先判断后执行。
1.break和continue的区别
前面有个break跳出,这里又来一个continue跳出,那两者有什么区别呢?
我们可以来比较下面的代码:
//1.break版
int main()
{
int count = 1;
while (count<10)
{
if (count == 5)
{
break;
}
printf("我真帅!第%d次呼喊\n",count);
count++;
}
printf("呼喊完毕\n");
return 0;
}
//2.continue版
int main()
{
int count = 1;
while (count<10)
{
if (count == 5)
{
continue;
}
printf("我真帅!第%d次呼喊\n",count);
count++;
}
printf("呼喊完毕\n");
return 0;
}
代码只在if语句中不同,那运行结果是什么呢?
我们可以看到,break版在while循环本应循环9次的时候,只呼喊了4次,然后跳出去呼喊完毕,而continue版呼喊了4次之后不在呼喊又不说完毕。
那我们先来了解一下break和continue的定义:
break在while循环中的作用:
其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。 所以:while中的break是用于永久终止循环的。
continue在while循环中的作用就是:
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。
所以,当上面的代码count==5
的时候在while语句中碰见break,就直接跳出了while循环并不再进来。而碰见continue的时候只是这一次不再执行下面的代码,然后又回去给while的表达式判断,当count==5
的时候碰见continue,又回去判断,又count==5
又回去判断又… 就导致了死循环。
所以当我们需要跳出循环的时候,要注意区分这两者的功效,千万不要用错,在呼喊自己帅的时候欲言又止。
3.for语句
for语句语法结构:
for(表达式1;表达式2;表达式3)
循环语句;
其中,表达式1 表达式1为初始化部分,用于初始化循环变量的。 表达式2 表达式2为条件判断部分,用于判断循环时候终止。 表达式3 表达式3为调整部分,用于循环条件的调整。
for循环语句先执行表达式1,然后判断表达式2,为真进入循环语句,为假退出循环,若进入循环语句执行后,最后再执行表达式3调整变量。然后再次进入表达式2判断进行循环。
我们先对比一下while循环和for循环的区别与细节,下面我要实现打印1-10的数字用for:
//1.while循环
int main()
{
int i = 1;//初始化部分
while (i <= 10)//判断部分
{
printf("%d\n", i);
i++;//调整部分
}
return 0;
}
//2.for循环
int main()
{
for(i=1; i<=10; i++) //合三为一
{
printf("%d\n",i);
}
}
可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹,for的使用频率也最高。
而for循环语句也比较容易理解:
int main()
{
int i = 0;
for (i = 0; i <= 10; i++)
//单次表达式;条件表达式;末尾循环体
//初始化赋值;判断条件;循环语句
{
printf("%d", i);//循环体
}
return 0;
}
for语句即在for的括号中,第一个;
前的是作为某一变量的初始化赋值语句, 用来给循环控制变量赋初值,第二个是判断语句,用于判断是否满足条件进入循环,第三个是循环后调整循环变量,避免无限循环。
而for语句和while语句中的break是一样的,但continue有所区别:
for循环中的continue跳过continue后边的代码,去了调整部分,调整循环变量,不容易造成死循环。
while循环中,continue跳过continue后边的代码,直接去到判断部分。
4.do while语句
do语句的语法结构:
do
{
循环语句
}while(表达式);
do…while循环和while类似,但是区别在于do…while循环会直接执行一次,不管表达式判断真假,先执行一次再到while处判断,也就是先执行,后判断,判断真假作为再次进入循环的依据。
比如:
int main()
{
int i = 0;
do
{
i++;
} while (i <= 10);
// 与while循环同样的判断条件但结果多1,证明在相同条件下
//do while语句比while语句多执行一次循环体
printf("%d", i);//i=11
return 0;
}
do 语句在循环中至少执行一次,使用场景局限,并不是经常使用。
5.小练习
知道了上面的内容,我们来写一个练习:
1.编写代码,演示多个字符从两端移动,向中间汇聚。比如这样子的:
//我要打印hello,那么就这样子打印:
h o
he lo
hello
//从两边到中间
代码:
#include <windows.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char arr1[] = "hello! today is a good day!";
//你想打印的内容
char arr2[] = " ";
//空屏幕
int right = strlen(arr1)-1;
//strlen计算字符串长度,减1表示字符串最后字符的下标
int left = 0;
//首字符下表标
while (left <= right)//循环条件:最左下表和最右下表不等
{
arr2[left] = arr1[left];//跟空屏幕交换字符,然后打印
arr2[right] = arr1[right];
left++;//最左的交换打印后向右移一位
right--;//最右的交换打印后向左移一位
printf("%s\n", arr2);//打印
Sleep(1000);
//执行挂起一段时间,就是停顿时间,单位是毫秒,所以这里是1s
system("cls");
//system是库函数,用来执行系统命令的,cls表示清屏
//所以上面的打印会清空然后再打印下一次内容
}
printf("%s\n", arr1);
//最后一次还是会清屏,那我跳出循环后再打印一次就完整了。
return 0;
}
四、goto语句
从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程,例如一次跳出两层或多层循环。这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环,相当于一个任意门。
我们可以来写一个让电脑关机的程序:
#include <windows.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char input[10] = { 0 };
//设置一个字符串让你输入
system("shutdown -s -t 60");
//system是库函数,用来执行系统命令的
//shutdown -s是关机,后面加上-t 秒数 是多少秒后关机
again:
printf("电脑将在1分钟内关机,如果输入:我是憨批,就取消关机!\n请输入:>");
//提示你输入
scanf("%s", input);//输入
if (strcmp(input, "我是猪") ==0 )
//strcmp字符串比较函数,如果相同就返回0
{
system("shutdown -a");
//shutdown -a是取消关机
}
else//如果输入不一样
{
goto again;//跳转回去再让你输入,1分钟后就真的关机了
}
return 0;
}
这就是goto的用处,返回某一处标记的地方。但不用goto语句我们同样可以用while语句去实现这个功能,其实goto语句真正适用的地方在于深层循环嵌套想出来的时候,比如
int main()
{
for ()
{
for ()
{
for ()
{
if ()
{
goto here;
}
}
}
}
here:
//重见光明
return 0;
}
五、猜数字小游戏
根据这一篇的内容,可以写一个猜数字小游戏,下面是猜数字小游戏的链接,感兴趣的小伙伴可以看一看哦:
好啦,本篇的内容就到这里,小白制作不易,有错的地方还请xdm指正,互相关注,共同进步。
还有一件事: