文章目录
我们知道C语言是结构化的程序设计语言,结构指的是顺序结构、选择结构、循环结构,C语言可以实现这三种结构。
我们写的代码是从上往下写的,而编译器也是从上往下一个一个读取代码,但这个有一个特别要注意的地方是,C语言是从main函数开始往下读取代码的,这里我们补充一个知识点。
我们说main函数是程序的入口,一个项目中可以有多个.c文件,但只允许有一个main函数,main函数有且只有一个,main函数也叫主函数。
回归正题,我们可以使用if和switch来实现分支结构。
if和else
if语句
if语句的语法形式:
if(表达式)
语句;
if语句执不执行,取决于表达式为真或为假,表达式为假,if语句不执行,表达式为真,if语句执行。
而在C语言中非0为真,0为假,简单点说,就是如果表达式为0,语句就不执行,表达式为1,语句执行。
例子:
#include <stdio.h>
int main()
{
if(1)
{
printf("hehe");
}
return 0;
}
最后输出的结果是:hehe。
表达式为非0(1),则语句执行。
当表达式为0时:
#include <stdio.h>
int main()
{
if(0)
{
printf("hehe");
}
return 0;
}
什么都不输出,具体效果,可以自行复制这串代码,在编译器里验证。
或者我们换一种写法:
#include <stdio.h>
int main()
{
int a = 0;
if(a)
{
printf("hehe");
}
return 0;
}
同样是不会打印。
else
if语句还可以配合else语句来一起使用。
if和else合起来才是一条完整的语句,才可以实现真正的分支作用。
分支语句就像一条岔路口,你选择走了A,就走不了B,if和else是一样的,当一起出现了if和else,要么走if,要么走else,编译器运行代码绝对不会走了if又走else。
例子:
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
if(a > b)
{
printf("hehe");
}
else
{
printf("haha");
}
return 0;
}
这里的if语句中的表达式"a>b"可以理解为实际情况a小于b时,if语句中是a>b,那这个表达式为假,为假则表达式不成立,那么自然而然的就执行else语句了,当if不成立时,else语句则执行。
我们再举一个例子,当a是奇数时则执行if,当时a是偶数时就执行else,这里就要使用到if···else语句。
if···else表达式如下:
if(表达式)
语句1;
else
语句2;
例子: 奇数则执行if,偶数则执行else。
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a); //输入3
if (a % 3 == 0)
{
printf("是奇数\n");
}
else
{
printf("是偶数\n");
}
return 0;
}
最后输出的是奇数。
悬空else
悬空else问题,else总是和最接近的if相匹配
我们看这段代码:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("haha\n");
else
printf("hehe\n");
return 0;
}
这段代码最终会输出什么?什么都不输出。
我们知道一个原则,else总是和最接近的if相匹配,当a=0,if表达式是a=1时,if表达式则不成立,if不成立,那么就走else,但这段代码中有两个if,而else和最接近的if相匹配,else和第二个if相匹配,而if表达式又不成立,但else是和第二个if相匹配的,所以也走不了else,最终的结果就是什么都不输出。
如果是这样写是不是更好区分呢
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a = 0)
{
if(a = 0)
printf("haha\n");
}
else
printf("haha\n");
return 0;
}
或者再换一种写法
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a = 1)
{
if(b = 2)
printf("haha\n");
else
printf("hehe\n");
}
return 0;
}
嵌套if
在上述else悬空问题中,在例子中使用到的if里面套if、else语句,这就是嵌套if。
在if···else语句中,else可以和另一个if语句语句连用,构成多重判断。
例子:我们在输入0的时候输出0,-1显示负数,1显示正数
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
if (a == 0)
printf("0\n");
else if (a > 0)
printf("正数\n");
else
printf("负数\n");
return 0;
}
else···if 和if一样有表达式。
与下面要说的switch相比if···else语句更适合表示一个范围,而switch适合表示一个确定的数。
if···else语句中也可以使用到关系操作符,如例子中的a=0中的“=”,就是关系操作符中一种,也可以使用逻辑操作符,逻辑操作符对于if···else语句的使用有重大帮助,但此篇只讲分支和循环语句,此篇不做具体描述,一笔带过,读者可以去搜索关于逻辑操作符的博客。
switch
讲完if···else语句,我们就来说说switch。
除了if语句外,实现分支结构,还可以使用switch语句。
我们可以switch看做是⼀种特殊形式的 if…else 结构,它可以⽤于判断条件有多个结果的情况。它把多重 else if 改成更易⽤、可读性更好的形式。
但它不同于if,switch表示一个确定的值去判断,而不能像if一样,可以表示一个大的范围。
switch表达式:
switch(表达式)
case 1 :
语句1;
case 2 :
语句2;
default :
语句3
switch根据表达式中的值,执行相应case分支,当case分支都不满足表达式时,则执行default分支。
需要注意的是:switch 后的 表达式 必须是整型表达式 ,
case 后的值,必须是整形常量表达式
例子:
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a); //3
switch (a % 3)
{
case 0:
printf("整除,余数为0\n");
case 1:
printf("余数为1\n");
case 2:
printf("余数为2\n");
}
return 0;
}
注意:case和后面的数字要有一个空格,每个case语句执行完成,之后需要加一个break才能跳出switch这个循环
当读者朋友去尝试上述代码是,得出的结果会是这样的:
达不到我们理想的效果,当我们输入3时,输出的不是“整除,余数为0”,而是把所有case都打印了一遍,这是因为当switch执行完case 0时,没有限制它的条件,没有告诉他,执行完case0就停止执行。
那么我们要怎么样告诉编译器执行完一个语句后就停止执行switch语句呢?
这个时候就要使用break
switch中的break
当没有switch语句中没有break时,执行完case 0后语句不会停止,会继续读下去,直到读完整个switch语句。
原本我们要的效果是当3整除3后,打印“整除,余数为0”,但没有break的限制,switch语句就会一直执行下去。
例子:
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
switch (a % 3)
{
case 0:
printf("整除,余数为0\n");
break;
case 1:
printf("余数为1\n");
break;
case 2:
printf("余数为2\n");
break;
}
return 0;
}
注意:所以在switch语句中break很重要,但也是不是每个case都要加上break,这个要看实际需求。
switch语句中的default
在switch语句中default的作用相当于if语句中的else,当不执行if时,则执行else,defaut也是一样,当case都不满足表达式时,则执行defauilt
例子:当输入1-5的数字时,则输出工作日,输入6和7时,则输出休息日,输入其他数字时,则输出显示输入错误
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
switch (a)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
case 6:
case 7:
printf("休息日\n");
default:
printf("输入错误\n");
}
return 0;
}
当所有的case都不满足于表达式时,则执行default。
switch语句中的case和default的顺序问题
case和default没有顺序要求,default也可以放在case前面,这都不影响代码的执行,default的优先级是没有case高的,就算default在case前面,也不会先执行default语句的内容。
但建议读者朋友都把default放在switch语句的后面处理。
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
switch (a)
{
default:
printf("输入错误\n");
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break;
case 6:
case 7:
printf("休息日\n");
break;
}
return 0;
}
for循环
C语言提供了3种循环结构,for循环是其中的一种,在3种循环结构中,for循环是最常用的,for循环对比其他两个循环结构,他的表达式最集中,如果代码量大的话,需要修改循环中的表达式时,表达式很分散,不利于我们修改,而for循环完全没有这样的顾虑。
语法形式:
for(表达式1;表达式2;表达式3)
{
语句;
}
表达式1:用于循环变量的初始化
表达式2:用于循环结束的条件的判断
表达式3:⽤于循环变量的调整
执行流程:首先执行表达式1,把变量初始化,再执行表达式2,判断循环的结束条件,再执行表达式3,如果表达式2 !=0则执行表达式3,表达式2 = 0,则不执行表达式3,表达式是否为0,决定for循环是否结束,为0结束循环,不为0则循环继续。
需要注意的是,表达式1,在整个for中只执行一次。
C语言中判断真假,用0和非0来判断一个数为真还是为假,0为假,非0为真。
注意:表达式与表达式之间要用分号(;)隔开。
例子:打印1-10的整数
#include <stdio.h>
int main()
{
int a = 0;
for (a = 1;a <= 10; a++)
{
printf("%d ", a);
}
return 0;
}
while循环
while语句的语法结构和if语句很相似。
我们对比一下:
while (1)
printf("haha\n"); //一直打印haha
if (1)
printf("haha\n"); //打印一次haha
这就是他们的不同之处,while实现的是循环效果。
while的执行流程:上来首先就判断表达式的值是否为0,值为0,循环结束,值不为0,循环语句执行,循环语句执行完成,再上来判断是否为0,不为0,循环语句执行,循环往复,直到遇到break或者表达式为0,循环结束。
例子:使用while打印1-10的整数
#include <stdio.h>
int main()
{
int a = 1;
while (a <= 10)
{
printf("%d ", a);
a++;
}
return 0;
}
do···while
语法形式:do···while是3中循环语句中使用最少的一个,for和while都是先判断表达式,表达式条件满足再执行循环语句,不满足则跳出循环
而do···while则是先进入循环体,执行循环语句,然后再执⾏ while 后的判断表达式,为真就继续执行循环语句,为假就跳出循环
do
{
语句;
}while(表达式);
执行流程: 先执行“语句”,执行完语句,在去执行“判断表达式”,判断表达式 !=0,则继续执行循环,执行循环语句;判断表达式==0,则跳出循环,循环结束。
所以 do while 语句中循环体是⾄少执⾏⼀次的,这也是 do while 循环特殊的地⽅。
例子:
#include <stdio.h>
int main()
{
int a = 1;
do
{
printf("%d ", a);
a++;
} while (a <= 10);
return 0;
}
需要注意的是判断表达式括号后面要加上分号——while(表达式);
循环中break和continue的作用
在循环中,我们会遇到很多问题,比如达到某个效果时,我们需要循环结束,或者我们不需要某个数字,我们需要跳过这个数字的打印,而C语言为这种情况也做了解决方法。
break:⽤于永久的终⽌循环,只要 break 被执⾏,直接就会跳出循环,执行循环以外的代码
continue:跳过本次循环,continue的作用是跳过continue后面的代码
需要注意的是continue在 for 循环和 while 循环中有所 差异的。
while循环中的break和continue
break举例
#include <stdio.h>
int main()
{
int a = 1;
while (a <= 10)
{
if (5 == a)
break;
printf("%d ", a);
a++;
}
return 0;
}
打印1 2 3 4后,当a = 5时,循环停在了break,不再打印,不再循环,跳出了循环。
break的作用就是永久终止循环,遇到break循环就结束。
当以后在循环时,需要达到某种循环效果,不需要循环继续下去的时候,就可以使用break永久的终止循环。
continue举例
把break换成continue,代码执行会发生什么?
#include <stdio.h>
int main()
{
int a = 1;
while (a <= 10)
{
if (5 == a)
continue;
printf("%d ", a);
a++;
}
return 0;
}
当a==5时,continue执行跳过本次循环,重新来到while判断表达式进行判断,代码走到if时,a == 5遇到continue再次跳过本次循环,这样就死循环了。
在这里如果循环变量的调整(a++),放在if语句前面,那进入while语句的时候,a就会先加1,死循环就不会产生了,具体效果,可以复制上述例子中的代码,读者朋友自己在编译器中尝试。
for循环中的break和continue
break 举例
和while循环中的break是一样,for循环中的break也是永久终止循环的作用。
例子:
#include <stdio.h>
int main()
{
int a = 0;
for (a = 1; a <= 10; a++)
{
if (5 == a)
break;
printf("%d ", a);
}
return 0;
}
和while循环循环是一样的,当 a == 5时,break终止循环。
continue举例
#include <stdio.h>
int main()
{
int a = 0;
for (a = 1; a <= 10; a++)
{
if (5 == a)
continue;
printf("%d ", a);
}
return 0;
}
for中continue和while的就有所不一样的,前面说过,for循环相比于while和do···while循环,for的表达式是集中的,当 a = 5 时,跳过本次循环,循环继续,来到循环结束的条件的判断,符合条件,就直接到了循环变量的调整,a++之后5就变成了6,所以for循环中的cotinue不会像while和do···while一样产生死循环。
do while循环中的break和continue
do···while语句中的break和continue的作用和while语句中作用是一样的。我们看下面例子代码,具体可以拿上面while的例子对比效果。
循环嵌套
上述我们说了3种循环语句,for循环、while循环、do···while循环,但这三种循环还能一起使用,使用的效果会更好,这种一起使用的方式就叫循环嵌套。
例子中我们使用for循环来演示循环嵌套。
例子:使用两个for循环,循环嵌套打印出九九乘法表
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
for (a = 1; a <= 9; a++)
{
for (b = 1; b <= a; b++)
{
printf("%d * %d = %d\t", a, b, a * b);
}
printf("\n");
}
return 0;
}
goto语句
说完分支和循环,C语言中还有一个特殊的语句,叫goto 语句和跳转标号, goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。
例子:
#include <stdio.h>
int main()
{
int a = 0;
goto nux;
printf("haha\n");
printf("hehe\n");
nux:
printf("xxx\n");
return 0;
}
但也要慎重使用goto语句,乱用goto语句的话可以会导致一些意想不到的问题,比如导致在函数内部随意乱跳转,打乱程序的执⾏流程,所以能不使用就不使用。
goto语句也并非一无是处,他可以在多重循环嵌套中一次性跳出循环。我们要终止一个循环就要使用一次break,但在多重循环下呢?所以goto语句的使用要根据实际情况去使用,但还是建议能不使用就不使用。
以上就是C语言之《分支和循环语句》的全部内容,如有错误处(如某个语句讲的有问题,演示代码例子有错误,有错别字等),可以在评论区指出,感激不尽!