分支与循环是C语言中很重要的知识,主要讲的是语句,学完了,可以编写更复杂的代码。
前言
C语言是一门结构化的程序设计语言
支持三种结构:
顺序结构:
选择结构:if switch
循环结构:for; while ;do while
if语句
if语句的语法(if在英文中是如果的意思)
//if(表达式)
// 语句;
表达式为真即成立,则执行;表达式为假即不成立,则不执行。
在C语言中,0为假,非零表示真;即表结果为0,语句不执行;结果为非零,则语句执行。
例子:判断一个整数是否为奇数
#include<stdio.h>
int main()
{
int num=0;
scanf("%d",&num);
if(num%2==1)
printf("%d为奇数\n",num);
else
printf("%d不是奇数");
return 0;
}
else
如果表达式为假,还需执行什么操作的话可用else,else的英文意思是否。
if与else构成if...else...语句了,语法形式如下:
if(表达式)
语句;
else
语句;
例子:判断是否成年,>=18,成年;否则就输出未成年。
#include<stdio.h>
int main()
{
int age=0;
scanf("%d",&age);
if(age<=18)
printf("未成年");
else
printf("成年");
return 0;
}
很简单!
分支中包含多条语句
默认在if和else语句中默认都只控制一条语句,如果多条,可以加括号。
例如 成年了,具有完全民事行为的能力
#include<stdio.h>
int main()
{
int age=0;
scanf("%d",&age);
if(age<=18)
printf("未成年");
else
{
printf("成年\n");
printf("具有完全民事行为的能力");
}
return 0;
}
反例
这是因为第二个打印不受else控制,连在一起是因为if语句中的printf没有换行符不影响比较。
嵌套
嵌套是指,一个代码中有多个if...else语句构成。else可与另一个if连用,构成多重判断。
简单的例子有,输入一个整数,判断是正数还是负数或者是零
#include<stdio.h>
{
int n = 0;
scanf("%d",&n);
if(n==0)
printf("为0");
else if(n>0)
printf("正数");
else
printf("负数");
return 0;
}
也可以这样写
#include<stdio.h>
int main()
{
if(n==0)
printf("为0");
else
{
if(n>0)
{
printf("正数");
}
else
{
printf("负数");
}
}
}
练习
输入一个人的年龄
<18,打印少年
18至44,打印青年
45至49,打印中老年
60至89,打印老年
90以上打印老寿星
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d",&age);
if(age<18)
printf("少年");
else if(age<44)
printf("青年");
else if(age<59)
printf("中老年");
else if(age<89)
printf("老年");
else
printf("老寿星");
return 0;
}
也可以这样写
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d",&age);
if(age<18)
{
printf("少年");
}
else
{
if(age<44)
{
printf("青年");
}
else
{
if(age<59)
{
printf("中老年");
}
else
{
if(age<89)
{
printf("老年");
}
else
{
printf("老寿星");
}
}
}
}
}
看你适应哪种。
悬空else问题
如果有多个if和else,可以记住这样一条规则,else总是跟最接近的if匹配。
比如上图代码,else跟第二个if匹配。vs2022会自动调整代码风格
可以看出这代码啥也不输出,为什么
因为代码if是先从if (a == 1),后if(b == 2)开始判断的,而此时a = 0,连代码都进不去,不符合。
如果需要以第一个if为限制条件可以这样改更容易理解
如果需要if与第一个if配对,可以这样改
所以写代码尽量养成良好风格,不要出现悬空else如第一幅图一样的代码。
关系操作符
C语言用于比较的表达示,称为比较表达式,里面使用的运算符称为关系运算符
主要有:
>小于运算符
<大于运算符
>=大于等于运算符
<=小于等于运算符
==相等运算符
!=不等于运算符
关系表达式通常返回0和1表示真假
C语言中,0表示假,非零值表示真
这里很简单,有一个小小的知识点要注意一下
赋值运算符=与相等运算符==
生活中我们常用的等于号=在C语言中是赋值运算符,并不是相等,例如a=1,是把1的值赋给a的意思。
而相等运算符是==,它们是有区别的,我写个例子
这里的=是赋值的意思,我们可以看到,一开始a=0,但程序仍会打印hello world,这是因为在if(a=1)中,赋值运算符把1的值赋给了a。
而这副图什么也不打印,这是因为if中的运算符是相等运算符,而此时a=0,不打印。
还有一些知识点
多个运算符不宜连用
例如,我写了个if语句。我想要括号里的条件是i<j<k这样子的if(i<j<k)。
实际上,计算机是从左到右识别的,如果当它发现你输入的例子满足i<j。计算机理解是(i<j)<k
它会先判断i<j是真是假,真返回1,假返回0;再用返回的数去比较是否小于k。
虽然生活中是可以这样子i<j<k用的,但在编程中不行,这样可能与自己程序所要的效果背道而驰。
例子
可以看到我要看青年的范围,可我输入10时仍然会打印青年,为什么?
这是因为先看18<=age,很明显18>10;不成立,为假返回0
然后再比较age<=35,由于前面返回0,所以现在是0<=35,成立了,为真返回1,那么表达式成立了,成立后干什么?当然是执行了,于是就打印青年。
作者曾经踩过坑,百思不得其解,当时不明白,好再最后懂了。,把它单独开一个知识点。
那么,我觉得这样写很不错,该怎么改?可以这样
为了更体现这代码运行,我加了else,处理一下比如10这种结果。
看,现在可以了,那么&&又是什么呢?别急,新知识点来了。
逻辑操作符
!:逻辑取反运算符(改变表达式的真假,例如a=100这表达式取反即a!=100意思是a不等于100)
&&:与运算符,并且的意思(用它相连的个式子都成立,判断才为真,可记为全真则真,一假为假。)
||:或运算符,就是或者的意思(用它相连的式子,只要有一个成立,那么判断为真,可记为一真为真)
来几个简单的例子
如果说3至5月份是春天,用代码怎么表示
如果说12月,1月,2月是冬天,用代码怎么表示
短路
这里有个小小的知识点提一下,我们都知道程序都是从左向右运行的,像a&&b这样,如果表达式a返回0,即表达式a为假,此时程序便结果判定为假,不会继续往后判断变量是否符合b即不管b了即可形象称为短路。说以我们在取范围时,一定要将范围较大或者值小的按顺序放左边。
判断闰年
if语句及一些不可不知道的小知识都讲完了,来综合运用一下
能被4或400整除并且不能被100整除的年份时闰年
条件操作符
条件操作符也叫三目操作符(操作三个数),形式如下:
exp1? exp2 :exp3
逻辑是,exp1为真,exp2计算;exp1为假,exp3计算。
这个很好用,例如比大小
switch语句
除if语句外,C语言还提供了switch语句来实现分支结构,switch英语的名词开关,闸,转换器,道岔的意思
switch是特殊的if...else语句结构,用来判断条件有多个结果的情况,与多层嵌套if...else相比,如果问题允许用switch语句来解答则更可读,更易用。
switch(expression)
{
case value1:
case value2:
default:statement
}
这是例子,根据表达示expression不同的值,执行相应的case分支,如果找不到符合值,就执行default。
switch有两点要注意:
expression必须是整形表达示
case后的值必须是整形常量
default
default,英语有否定的意思,不履行,违约;默认,系统设定,缺席;弃权;欠缺,缺乏
如果输入的值无法与结果case匹配,就不要处理,可以用default,例如default:printf("错误");
if与switch语句的简单对比
例子,输入一个值,就叫n吧,计算n%3即除以3的余数。
如果用switch语句改写
上述代码中,有几点要注意
case和后面的数字之间必须有空格。
每一个case语句的代码执行完成后,需要加上break,才能跳出这个switch语句。
switch语句中的break
每一个case语句的代码执行完成后,需要加上break,才能跳出这个switch语句。如果没有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("工作日");
break;
case 6:
case 7:
printf("休息日");
break;
default:
printf("错误");
break;
}
return 0;
}
break
break,英语打破,打碎的意思。break的作用是跳出相应的代码。在不同的语句中,因语句的执行逻辑有差异,break的作用也有些细微的差别。
while语句
C语言提供了三种循环语句,while就是其中的一种。while语句与if语句的结构非常相似,区别在于条件为真时,while会一直循环执行,直至条件为假。
其执行流程:
while(条件)——》判断——》条件为真——》执行
|——》条件为假——》break,结束。
往复循环上述步骤。
while(表达式)
语句;//如果循环体想包含更多语句,可以加上大括号
可以敲代码与if语句对比一下
这样,就比较直观,判断为真,while语句会一直循环执行。if判断完,只执行一次。
while循环的简单实践
打印1到10:
输入一个正整数,逆序打印这个整数的每一位
思路:%10取余数可逆序分离出每一位,可先%10得余数打印,再/10减少位数。
do while语句
do while语句也是while循环,只不过do while区别就是我先执行后判断,若为真,则继续执行下去,若为假,则break,结束。即我先do(做)了再说。
敲代码看看
所以在do while语句中循环体是至少执行一次的,这是do while循环特殊的地方。
先执行后判断的do while自然有其用武之地
来看这个练习:
输入一串数,来判断其有几位数
思路:n/10能除几次,就有几位数。然后我再定义一个变量,每除一次,这个变量就加一,那么结果此变量的值就是这串数的位数。
之所以用do while是因为如果即使n=0时,也是一位数,要统计的,此时先执行就会把0也算上一位。当然我试了一下,还是有些数有局限,这就不展开讨论了,可自己试试。
for循环
for循环是三种循环中使用最多的
for(表达式1;表达式2;表达式3)
表达式1:用于变量的初始化
表达式2:用于循环的条件判断
表达式3:用于循环变量的调整
流程:
![](https://i-blog.csdnimg.cn/direct/7ad0007b3be1461c88777fae1149c86b.png)
![](https://i-blog.csdnimg.cn/direct/a018df92f6d8453099678ad6d3d338b0.png)
break和continue语句
在循环执行的过程中,有些特殊情况需要我们提前终止循环。C语言提供了break和continue这两个关键字,令我们能够操作。其中break在上文中简单提过。来提一下continue,英文是继续。
break的作用是用于永久的终止循环,只要break被执行,直接就会跳出当前循环,继续往后执行代码。
continue的作用是跳过本次循环continue后边的代码,在不同的循环语句中有所差异。
下面就来细细探讨。
while循环中的break和continue
break举例
打印了1,2,3,4后,当i等于5的时候,就执行break,程序终止,不再打印,不再循环。也可以理解为打破了这个循环。
所以break的作用就是永久的终止循环,只要break被执行,break外的第一层循环就终止了,那么我们在循环中,想要在某种条件下终止循环,则可以使用break来完成我们想要的效果。
continue举例
把上述代码换成continue会有什么效果呢?答案是死循环,continue跳过后边的打印和i+1,回到了while(i<10)这的判断步骤,然后此时i等于5,条件为真,执行循环,然后又有到了if语句种的continue,接着跳过回到判断。如此循环往复。
你会看到跟上图差别,程序没有执行结束和退出,一直在循环。
来个直观一点的操作,我F9弄了个断点,弄了断点后,每按F10程序可以每执行一步,打开监视,输入监视的项i,可以看出此时i=5,然后我再按F10。
再执行,程序就会回到while(i<10)判断这里,说明continue跳过了后边的代码。之后反复按F10就会看到程序反复在6至9行的continue这跳转,又回到6行
补充:执行调试,在窗口这里可以看到监视的选项,任一点一行代码按F9可以创建断点,然后每按F10,程序就往下执行一次,然后到断点停止。这样可以看到程序具体时怎么执行的。这正是调试的作用。
for循环中的break和continue
for循环执行流程图
break举例
break直接跳出来了,终止了。
continue举例
执行到continue后,直接跳到调整i++部分(看流程图),没有打印即结果中没有5。
do while中的break与continue几乎是一模一样的,作者懒癌晚期,就懒得写了。可以自己去试试。
循环的嵌套
解决问题时,三种循环经常会嵌套在一起。下面就以一道练习收尾了。
练习:找出100至200 之间的素数并打印
素数:只能被1和本身整除的数
思路:循环产生100至200的数字,再循环产生不是它本身和不是1的数,最后相除,余数等于0的排除,剩下的就是素数。
#include<stdio.h>
int main()
{
int i = 0;
for (i = 100; i < 200; i++)//产生100至200
{
int j = 0;
int flag = 1;//假设i已经是素数
for (j = 2; j < i; j++)//j不等于1和i本身
{
if (i % j == 0)
{
flag = 0;//不是素数
break;
}
}
if (flag == 1)
printf("%d ", i);
}
return 0;
}
本文是学习经验与书籍相结合的总结,如有误欢迎指出和讨论。