目录
今天我们给大家带来的是 分支与循环语句相关内容的讲解
三种结构介绍
在C语言中共有三种结构:顺序结构,选择结构,循环结构
顺序结构
顺序结构是最常见的一种结构,就是从上往下按顺序执行语句
选择结构
选择结构就是如果你选择了选项a,那么就会执行a选项内的内容,其余选项内的内容则不会执行,也就是我们本章要讲的“分支”
循环结构
循环结构就是需要在一定条件下执行多次的一种结构,当条件不满足的时候则会跳出循环
图解如下:
介绍完三种结构之后,那么就来开始我们今天的重点——分支与循环
分支
在分支语句中,我们可以用if,switch来实现分支的效果
if 语句
if 语句的用法介绍
我们都知道 if 的意思为如果,那么我们在C语言该怎么使用他呢?我们先来看一看下面这一串代码
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age == 18)
printf("可以谈恋爱了\n");
return 0;
}
我们可以知道,当我们输入的结果为 18 的时候,则屏幕上会告诉你 你可以谈恋爱了。如果 age 不为 18 的时候,则不会有任何结果。
那么问题来了,我们如果真的要进行判断的话,仅仅只是一个if真的够吗?我们能否有办法实现如果未成年,就执行不给谈恋爱的方法呢?
还真有,这就需要引出我们的另一位主角——else,else的作用就是:如果if内的语句不执行,则执行else内的语句,如下
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("可以谈恋爱了\n");
else
printf("未成年\n");
return 0;
}
当我们输入的年龄大于或者等于18的时候,屏幕就告诉你你可以谈恋爱了,而如果是未成年的话,则会被告知:未成年
另外需要注意的一点是:一个if 语句只能控制一个语句,如果需要控制多条的话,则需要加上{ }
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("可以谈恋爱了\n");
printf("呜呜呜\n");
return 0;
}
由图可得,我们输入的值无论是不是18,呜呜呜都会被打印出来,只有当我们输入的值为17时,才会只打印呜呜呜,这是因为 if 只能控制得到第一个printf,第二个printf不归他管
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
{
printf("可以谈恋爱了\n");
printf("呜呜呜\n");
}
return 0;
}
当我们用{ }括起来之后,也就代表{ }内的语句都归 if 管,当我们输出17时,则没有结果
if 的嵌套使用
if 语句在C语言中还有另一种用法,当我们进行了一次判断之后,我们还可以在 if 内部再加一层 if ,如下:
#include<stdio.h>
int main()
{
int hight = 0;
scanf("%d", &hight);
if (hight >= 145)
{
if (hight < 200)
{
printf("太高了,不能玩");
}
else
{
printf("身高合适,可以玩");
}
}
else
{
printf("身高不够,不能玩");
}
return 0;
}
当我们判断完身高确实>=145,则进入下一层判断:身高会不会太高,如果身高<200,则会打印一个 太高了,不能玩 ,否则打印 身高合适,可以玩 。
注意,如果我们的 if 在 else 内部嵌套的话,那么就可以将其写成else if。如果 if 的条件不符合,则走 else if ,如果 else if 也不符合,就走 else
我们这里又一道题目:
输入成绩,如果>=90,则打印 “优秀”,如果>=75但<90,则打印 “良好”,如果>=60但<75,则打印 “一般”,如果低于60,则打印 “不及格”。代码如下:
#include<stdio.h>
int main()
{
int grade = 0;
scanf("%d", &grade);
if (grade >= 90)
{
printf("优秀");
}
else if (grade >= 75)
{
printf("良好");
}
else if (grade >= 60)
{
printf("良好");
}
else
{
printf("不及格");
}
return 0;
}
注:如果走了第一个else if,则证明grade不满足 if 里的条件
悬空else问题
在开始讲之前,我们先来看一组代码:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
请问这一段代码的结果是什么呢?
答案是:不输出任何结果。
为什么会这样?这是因为在C语言中,else 总是与他最近的那个 if 相匹配,而在上面那段代码中,else 其实是和第二个 if 在一起的,并且只有当a==1的时候才会进行下一步的判断,不巧的是, a != 1,所以根本就没有进行下一层判断。
而这种问题也是可以避免的——加{ },如下:
#include<stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
}
else
printf("haha\n");
return 0;
}
这次的结果就会输出一个haha,因为加了{ }之后,else和第一个 if 相匹配
操作符
1. 关系操作符
常见的关系操作符主要有以下六个:> < <= >= != ==
前面五个不必多说,我们来重点看一看最后一个 == 。这个 == 很多时候会和 = 搞混,== 代表的是判断==两边相不相等,比如 b == 1,表示的就是判断 b等不等于 1,而如果是 b = 1,代表的则是将数字 1 赋值给变量 b。
2. 条件操作符
条件操作符的形式如下:exp1 ? exp2 : exp3
当我们的exp1为真的时候,返回exp2;若为假,则返回exp3。看一个例子:
#include<stdio.h>
int main()
{
int a = 10, b = 20;
int ret = a > b ? a : b;
printf("%d\n", ret);
return 0;
}
3. 逻辑操作符
逻辑操作符包括:逻辑取反运算符 ! 或运算符 || 与运算符 &&
注:在C语言中,0表示假,非0表示真
!
这时我们写了一个表达式,当我们在其前面加了一个逻辑反运算符的时候,如果该表达式为真,则加上!之后结果就为假,反之亦然
|| 与 &&
对于||与&&我们可以这样去理解:
|| :假如我现在需要张三和李四两个人里的其中一个来帮我搬桌子,只来了张三行不行?当然,因为我只需要两个人里的其中一个就可以了,只来了李四也是一样的,两个人都来了那更好,只有在两个人都没来的情况下才不满足我的要求
&&:现在我需要张三和李四一起来帮我,只来了其中一个行不行?不行,我要的是两个人都来,只要不是两个人都来,那就不满足我的要求
简单理解之后我们再进行进一步的解释,如果 || 两边只有一个表达式的结果为真,那整个的结果就为真,而&&两边只要有一个不是真,那么整个表达式的结果就为假,具体如下图:
那么了解完操作符的相关知识,那我们就来趁热打铁做一道题目吧!
判断闰年
注:能够被4整除但不被100整除的是闰年,或者能被400整除的也是闰年。代码如下:
#include<stdio.h>
int main()
{
int year = 0;
scanf("%d",&year);
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
{
printf("是闰年");
}
else
{
printf("不是闰年");
}
return 0;
}
switch语句
在C语言中,除了 if 语句能实现分支语句之外,还有switch语句也同样可以实现分支,常被用于有多种结果的情况,其格式如下:
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
需要注意的是:1. switch内的expression必须是一个整形表达式
2 .case后跟着的必须是整型常量表达式,并且case与表达式之间需要用空格隔开。
3 .如果所有的case都不满足的话,那么就会走default
我们来看一个例子:
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期一\n");
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("输入错误\n");
break;
}
return 0;
}
且看这里,当我们输入1时,屏幕上就会打印一个星期一,输入2时屏幕上就会打印一个星期二...或许有人会疑惑:为什么每一个case后面都要跟着一个break啊?那我们一起来看看,如果不加break的话,结果会变成什么样
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期一\n");
case 2:
printf("星期二\n");
case 3:
printf("星期三\n");
case 4:
printf("星期四\n");
case 5:
printf("星期五\n");
case 6:
printf("星期六\n");
case 7:
printf("星期天\n");
default:
printf("输入错误\n");
}
return 0;
}
可以看到,当我们输入了一个1的时候,所有的结果都被打印出来了,也就是说switch case语句在执行的时候,会一直往下找break,直到遇到break了才会停下来。而这种不一定每一个语句都加break的情况也可以运用在一些特殊的场景,如下:
#include<stdio.h>
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;
}
return 0;
}
当我输入1~5之间的数字的时候,结果都会打印工作日;而输入6~7时,则会打印休息日
循环
上文我们有提到,在C语言分为了顺序结构,选择结构与循环结构,而在循环结构中,又有三种语句可以实现循环:while循环,for循环,do..while循环
while循环
在开始讲while语句之前,我们先来看一看while语句的执行流程图:
由图我们可以看到,while循环会先有一个判断表达式,如果表达式内的值为0(为假),则跳出循环,如若结果为非0(为真),那么就会执行语句并进入下一次判断
假如我们现在要将1~10打印在屏幕上,那么我们就需要用到循环,如下:
#include<stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
i++;
printf("%d ", i);
}
return 0;
}
我们将while循环里的判断设置为( i < 10),而while循环内部我们也有 i++,每一次循环 i 的值都会加 1,当 i = 10 的时候,不满足判断表达式里的条件,则跳出循环。
练习
输入一个正整数n,求1^2+2^2+3^2+……+n^2(n^2表示n的平方)
代码如下:
#include<stdio.h>
int main()
{
int i = 0;
int x = 0;
int num = 0;
scanf("%d", &i);
while (x<=i)
{
num += x * x;
x++;
}
printf("%d\n", num);
return 0;
关键点在于:我们可以将每一次平方的结果放进num中
for循环
在开始讲for循环之前,我们也来看一看他的执行流程图:
for循环的表达式是这样的:
for(初始化;判断;调整)
{
//语句
}
他会先进行初始化和判断,在执行完语句之后才会调整。假如我们现在要用for循环在屏幕上将1~10的数字给打印出来,那么代码如下:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
那么在解释完for循环之后我们同样来做一道练习
练习
输入一个正整数n,求1^2+2^2+3^2+……+n^2(n^2表示n的平方)
这道题我们用while循环实现过,那如果用for循环我们该怎么实现这个代码?代码如下:
#include<stdio.h>
int main()
{
int i = 0;
int n = 0;
scanf("%d", &n);
int num = 0;
for (i = 1; i <= n; i++)
{
num += i * i;
}
printf("%d\n", num);
return 0;
}
do…while循环
同样的,在讲解该循环之前,我们先来看一看该循环的执行流程图:
由图可得,这个循环和另外两个循环可不太一样,do…while循环不管三七二十一,先将语句执行一次,然后再去进行判断,也就是说,使用了这个循环则至少会执行一次语句的内容,正是因为这个特性,所以do…while循环的使用场景比while和for循环少
我们再来看一看do…while循环的语法,如下:
do
{
//语句;
}while(表达式);
while后跟着的表达式就是进行判断的地方;
依然是打印1~10的数字在屏幕上,那么用do…while循环又会有什么不同?我们来看看:
#include<stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i += 1;
} while (i <= 10);
return 0;
}
那么在讲完do…while循环之后,我们再来看一看do…while循环一个比较常被用到的一个场景:
常用场景
#include<stdio.h>
void menu()
{
printf("*********************\n");
printf("**** 1. game ****\n");
printf("**** 0. exit ****\n");
printf("*********************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("进入游戏\n");
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
如上,我们使用do…while循环和switch case语句实现了一个简易游戏的菜单选择,当结果不为0或1是,就走default,打印输入错误并进入循环,只有当我们输入0的时候,do…while循环里的判断为假,这时才会结束程序。
break和continue语句
在上文中的三张执行流程图中,不知各位有没有发现,每一张里都有break和continue这两个东西。其实,break和continue是C语言中的两个关键字,在循环中被应用。
break:永久地终止循环,跳出循环并执行循环之后的语句
continue:跳过本次循环,并直接跳到判断部分准备进行下一次循环
注:break和continue在for循环和while循环中也有些许不同
这里我们先来看看break的实例:
#include<stdio.h>
int main()
{
int i = 1;
while (i < 10)
{
if (i == 5)
{
break;
}
printf("%d ", i);
i++;
}
return 0;
}
我们可以看到,当 i 在增大时,如果 i == 5,那么就会跳出循环,所以屏幕上只打印了1,2,3,4
我们再来看看continue的实例:
#include<stdio.h>
int main()
{
int i = 1;
while (i < 10)
{
if (i == 5)
{
continue;
}
printf("%d ", i);
i++;
}
return 0;
}
由屏幕上输出的结果不难看出,该段代码在执行的时候陷入死循环了。这是因为每一次碰到continue时,i==5,但还是<10,再次进入循环,如此往复,便成了死循环,图解如下:
相信看到这里你已经明白break和continue的区别了,那如果我们这里用的是for循环呢?
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
{
continue;
}
printf("%d ", i);
}
return 0;
}
我们可以看到,屏幕上除了5,1~10以内的数字都被打印了。这是因为当for循环碰到continue时,会先跳到调整部分,先将 i++给执行了,然后才去判断是否需要进行下一个循环
循环的嵌套
在C语言中,通常需要将循环嵌套在一起才能更好地将问题解决
我们来看两个例题
例题 1:打印乘法口诀表(9*9)
#include<stdio.h>
int main()
{
int i = 0, j = 0;
for (i = 1; i < 10; i++)
{
for (j = 1; j <= i; j++)
{
printf("%d * %d = %-4d ", i, j, i * j);
}
printf("\n");
}
return 0;
}
此处的第一个for循环代表有多少行,第二个for循环代表具体的每一行,而我们的 j 之所以要设置成 <i,是因为我们第一行打印1*1=1,此时i=1;第二行打印2*1=1 2*2=4,此时i=2……
例题 2:打印100~200之间的素数
#include<stdio.h>
int main()
{
int i = 0;
//生成100~200之间的数
for (i = 100; i <= 200; i++)
{
int flag = 1;
int j = 0;
for (j = 2; j < i; j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
{
printf("%d ", i);
}
}
return 0;
}
我们可以看到,第一层for循环表示的是将100~200之间的数字给表示出来,而我们要判断一个数字是不是素数的关键就在于:这个数字是否只能被1和他本身整除。所以我们第二个for循环代表该数字之前的所有数字(不包括0和1),将这些数字一个一个拿去与所要判断的数字试除,如果能被整除,则不是素数;如果不能,那么就是素数,打印下来。
而我们在该段代码中还引入了另一个变量flag并将其初始化为1,当一个数字不为素数的时候,就另flag为0。因为第二个for循环结束之后,无论是不是素数都会来到循环结束的地方,这时我们再来判断一下:如果flag=1,那么我们就打印 i,如果不为 1,那我们就不管。由此,我们的基础版素数判断就完成了。
问题来了,这个代码是最优的吗?不见得吧,102,104,106…都能被二整除,那我们就将这些数字全部跳过,而我们的修改方法就是让 i 从101开始,每次调整的时候都让 i+=2,如下:
#include<stdio.h>
int main()
{
int i = 0;
//生成100~200之间的数
for (i = 101; i <= 200; i+=2)
{
int flag = 1;
int j = 0;
for (j = 2; j < i; j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
{
printf("%d ", i);
}
}
return 0;
}
注:此处不再使用sqrt来进行再优化了
结语
那么我们今天关于分支与循环的相关内容就介绍到这里,如果大家喜欢的话,希望可以多多支持!!