一.C语言结构
在日常生活中,会有三种结构的语句:顺序结构、循环结构、选择结构。这三种语句结构广泛运用在日常生活中。作为解决日常生活问题的编程语言,自然也会有相同与生活中的语句结构,下面我们就来探索一下吧!
二.选择结构:if语句
1.语法形式
if语句的语法形式如下:
if(表达式)
语句
具体含义是:如果表达式成立,即为真,则执行下面的语句,否则就不执行。在C语言中,语句结果:非0表示真,0表示为假。下面给出一个例子来进一步认识if语句。
cpp
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num % 2 == 1)
printf("%d 是奇数\n", num);
return 0;
}
上述代码的意思是:先定义一个整型变量num,获取键盘输入值赋予num。如果num除以2余数为1,则打印:num时奇数这句话。整体代码的功能是判断输入的值是否为奇数。

左边图片是if语句的流程图,右边图片是判断是否为奇数的流程图。
2.else
(1)语句介绍
一个数字不是奇数,那么就是偶数了。上面我们实现了:判断一个数字是否为奇数,如果是则打印"是奇数",那如果不是呢?如果不是奇数的情况下,我们还想实现一些事情该怎们办?这时候就该用if-else语句了。下面展示if-else语句的语法形式:
if(表达式)
语句一
else
语句二
上述语句的意思是,如果表达式为真,则执行语句一。如果为假,则执行语句二。下面举例子熟悉if-else语句:
(2)代码练习
<1>判断奇偶数
题目介绍:输入一个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印偶数。
cpp
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num % 2 == 1)
printf("%d 是奇数\n", num);
else
printf("%d 是偶数\n", num);
return 0;
}
根据if-else 语句写出的判断奇偶数代码的解析:先定义一个整型变量num,用于接收输入的值,从而进行判断奇偶数。如果num除以2余数是1即num是奇数,则打印num是奇数;否则打印num是偶数。
<2>判断年龄
题目介绍:输入一个年龄,大于18岁就输出:成年,否则就输出:未成年。
cpp
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age>=18)
printf("成年\n");
else
printf("未成年\n");
return 0;
}
(3)分支包含多条语句
if-else语句默认只能控制一条语句,比如下方代码:
cpp
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)
printf("你变成大人了\n");
printf("你开心吗\n");
return 0;
}
上述代码中if语句下有两句语句。且无论age是否大于18,都会打印在屏幕上。这说明了if语句只能控制一条语句。下面对上面代码进行解释:先定义一个整型变量age,用于接收键盘输入的值,然后进入进行判断的if语句,如果age大于等于18,则打印"你变成大人了",然后出if 语句,遇到printf函数,便打印内部的参数:"你开心吗"。
因为if语句只能控制一条语句,所以当其包含多条语句时,就需要大括号把多条语句括起来。else语句也是相同的道理。下面给出代码示例:
cpp
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)
{
printf("成年了\n");
printf("可以谈恋爱了\n");
}
else
{
printf("未成年\n");
printf("不可以早恋哦\n");
}
return 0;
}
上述代码的解释:先定义一个整型变量age,用于接收键盘的输入值从而进行判断:如果age大于等于18,则打印:"成年了 可以谈恋爱了";如果没有满足age大于等于18这个条件,则打印:"未成年 不可以早恋哦"。
这里需要知道的是:当一些语句被大括号括起来,作为分支的结构,那么这些被括号括起来的语句就可以叫做:程序块或者复合语句。
(4)嵌套if语句
在日常生活中,往往不仅仅只有两层判断,有可能有多重判断。那么简单的单层if语句就不能满足需求。这时候就需要嵌套if语句。下面给出例子用于了解嵌套if语句:
<1>例子一
题目介绍:要求输入一个整数,判断输入的整数是0,还是正数或者负数。
cpp
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num == 0)
printf("输⼊的数字是0\n");
else//起始
if(num > 0) //这⾥的if 相当于嵌套在else语句中,形成了嵌套结构
printf("输⼊的数字是正数\n");
else
printf("输⼊的数字是负数\n");
//终止
return 0;
}
上面代码中从注释可以看出,起始和终止 之间的部分就是嵌套的if语句。
上述代码的解释:先定义一个整型变量num,用于接收键盘输入的值。然后进行判断:num是否等于0,等于0则打印:"输入的数字是0";如果不是0,则进入嵌套的if语句,判断是否大于0,如果大于0,则打印:"输入的数字是正数"。如果不大于0,也不等于0,则进入else语句打印:"输入的数字是负数"。
<2>例子二
题目介绍:输入一个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:非正数。
cpp
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num>0)
{
if(num%2 == 0)
printf("偶数\n");
else
printf("奇数\n");
}
else
{
printf("⾮正数\n");
}
return 0;
}
上述代码第一个if语句后面大括号内的程序块为嵌套的if语句。
上述代码的解释:先定义一个整型变量num,用于接受键盘输入的值。从而进行判断:如果num不满足大于0,则打印非正数;如果满足,则进入嵌套的if语句,继续判断num除以2,余数是否为0,如果余数为0,则打印偶数;如果余数不为0,则打印奇数。
以上就是嵌套if语句的语法,有了嵌套if语句,就可以完成更多复杂逻辑的判断。下面来练习一个习题吧。
<3>练习题
题目介绍:输入一个人的年龄,如果年龄为18岁,打印"少年" ;如果年龄在18岁-44岁打印"青年"; 如果年龄在45岁-59岁打印"中老年" ;如果年龄在60岁*-89岁打印"老年" ;如果90岁及以上打印"老寿星"。下面是代码实践:
cpp
//⽅法1
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age<18)
printf("少年\n");
else if(age<=44)
printf("⻘年\n");
else if(age<=59)
printf("中⽼年\n");
else if(age<=89)
printf("⽼年\n");
else
printf("⽼寿星\n");
return 0;
}
cpp
//方法二
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age<18)
{
printf("少年\n");
}
else
{
if(age<=44)
{
printf("⻘年\n");
}
else
{
if(age<=59)
{
printf("中⽼年\n");
}
else
{
if(age<=89)
printf("⽼年\n");
else
printf("⽼寿星\n");
}
}
}
return 0;
}
上述两个代码的解释:先定义一个整型变量age,用于接收键盘输入的值。从而进行判断:如果age小于18,则打印:"少年:;然后进入第一个嵌套if 语句,判断age是否小于等于44,如果满足则打印:"青年"······以此类推。
(5)悬空else问题
在正常写C语言代码的过程中,难免会遇到很多复杂的if-else语句在一个程序内部这种情况,这时候就会出现if-else语句配对问题,所以我们时刻应该记住else总是和最近的if语句匹配。下面给出例子来练习一下:
cpp
#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;
}
//上述代码的打印结果使空内容(什么也不打印)
上述代码有很多的if-else语句,所以会有if-else语句配对问题。下面用大括号对代码进行处理:
cpp
#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;
}
这样便可以更容易地看出if-else语句的配对情况。所以可以得出else语句总和距离最近的if语句配对,但也告诉了我们一个道理:在写代码的时候不要吝啬大括号,写的大括号可以提高代码的阅读性。
三.关系操作符
1.关系操作符的介绍
C语言用于比较关系的表达式,称为"关系表达式",里面使用的运算符就称为"关系运算符",主要有下面6个:
> 大于运算符
< 小于运算符
>= 大于等于运算符
<= 小于等于运算符
== 相等运算符
!= 不相等运算符
下面分别举六个运用了关系操作符的表达式的例子 :
a > b;
a < b;
a >= b;
a <= b;
a == b; //这里注意==和=是不一样的符号,前者是关系操作符,用于判断前后操作数是否相等;后者是赋值操作符,用于把后面操作数的值赋值给前面的操作数。
a != b;
2.关系操作符的原理
关系表达式通常返回0或者1,用于表示表达式的真假。在C语言中,0表示假,非0表示真。关系操作符常常用于if或者while语句中。
3.关系操作符注意事项
(1)分析
关系操作符需要避免的是:多个关系操作符不可以连用。例如下方代码:
i < j < k //左边示例的代码没有问题,编译器不会报错,但是使用起来不会达到预想的效果。因为关系表达式的运算顺序是从左至右。所以表达式可以化成(i<j)<k;又因为关系操作符运算时,返回值是0或者1,所以i<j如果为真,则该表达式的值就会变成1;为假就会变成0;剩下的运算就是k和0或者1比较大小了。
这样看来连写的表达式看起来的效果往往是词不达意,所以在今后书写代码时应该避免写连续的关系操作表达式。
那么我们怎样实现数学上的i < j < k 表达式呢?我们可以尝试下面的写法:
i < j && j < k //&&是并且的意思,这样就可以实现数学表达式i < j < k同样的效果了。
(2)证明
下面给出例题进行验证:
题目描述:我们输入一个年龄,如果年龄在18岁~36岁之间,我们输出青年。
cpp
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(18<=age<=36)
{
printf("⻘年\n");
}
return 0;
}
上述代码运行结果在我们输入10也会输出青年,我们可以改正代码 :
cpp
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age>=18 && age<=36)
{
printf("⻘年\n");
}
return 0;
}
三.条件操作符
1.分析
条件操作符也叫做三目操作符(有三个操作数),形式如下:
表达式1 ?表达式2 :表达式3 //左边代码的意思是:当表达式1为真则整个表达式返回表达式2的值,否则返回表达式3的值。这个三目表达式像是把if语句缩短成了一句话。
下面给出例子:
cpp
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
if (a > 5)
b = 3;
else
b = -3;
printf("%d\n", b);
return 0;
}
cpp
改造后:
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
b = a>5 ? 3:-3;
printf("%d\n", b);
return 0;
}
两种代码的效果是相同的,但是代码2比代码1更简洁。
2.练习题
下面给出一个练习题:
题目描述:使用条件表达式实现找两个数中较大值
代码实践:
cpp
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int m = a>b ? a : b;
printf("%d\n", m);
return 0;
}
四.逻辑操作符
逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
! :逻辑取反运算符(改变单个表达式的真假)。
&& :逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
|| :逻辑或运算符,就是或者的意思(两侧至少有⼀个表达式为真,则为真,否则为假)。
1.逻辑取反操作符:!
逻辑取反操作符的作用是把一个语句的真假取反,把本身为真命题的句子进行取反。比如flag为非0值,在C语言中为真命题,那么!falg为0值,在C语言中为假命题。下面给出代码验证:
cpp
#include <stdio.h>
int main()
{
int flag = 0;
if(!flag)
{
printf("do something\n");
}
return 0;
}
上述代码的解释:先定义了一个变量flag,并且初始化为0.下面进入if语句,如果!flag为真则打印:"do something"因为falg为0,所以!flag为非0值,在C语言中为真,所以代码的结果是打印出来:"do something"
2.逻辑与运算符:&&
&& 就是逻辑与运算符,也是并且的意思, && 是⼀个双目操作符,使用的方式是 a&&b , && 两边的表达式都是真的时候,整个表达式才为真,只要有⼀个是假,则整个表达式为假。
代码例子:月份是3月到5月是春天,那使用代码怎么体现呢?
cpp
int month = 0;
scanf("%d", &month);
if(month >= 3 && month <= 5)
{
printf("春季\n");
}
上述代码的解释:当输入的月份介于3和5之间时,打印春季。
上述代码的month >= 3 && month <= 5和5>=month>=3,两句代码的效果是不一样的!!!
3.逻辑或操作符||
|| 就是或运算符,也就是或者的意思, || 也是⼀个双目操作符,使用的方式是 a || b , || 两边的表达式只要有⼀个是真,整个表达式就是真,两边的表达式都为假的时候才为假。
代码例子:月份是12月或者1月或者2月是冬天,那么我们怎么使用代码体现呢?
cpp
int month = 0;
scanf("%d", &month);
if(month == 12 || month==1 || month == 2)
{
printf("冬季\n");
}
4.逻辑运算符练习
输入⼀个年份year,判断year是否是闰年
闰年判断的规则:
-
能被4整除并且不能被100整除是闰年
-
能被400整除是闰年
cpp
#include <stdio.h>
//代码1
int main()
{
int year = 0;
scanf("%d", &year);
if(year%4==0 && year%100!=0)
printf("是闰年\n");
else if(year%400==0)
printf("是闰年\n");
return 0;
}
//代码2
int main()
{
int year = 0;
scanf("%d", &year);
if((year%4==0 && year%100!=0) || (year%400==0))
printf("是闰年\n");
return 0;
}
上述代码1的解释:先定义了一个整型变量year,用于接收键盘输入的年份。然后进入if语句,如果可以被4并且不可以被100整除的数字,就打印闰年。进入第二个if语句,如果可以被400整除就打印闰年。
上述代码2的解释:2和1的区别就是2把1的两个if语句用逻辑或操作符替换掉了,具体效果是一样的。
5.短路
C语言逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是固定的。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为"短路"。
如前面的代码:if(month >= 3 && month<= 5) 表达式中&&的左操作数是 month >= 3 ,右操作数是 month<=5 ,当左操作数 month >= 3 的 结果是0的时候,即使不判断 month ,整个表达式的结果也是0(不是春季)。所以,对于&&操作符来说,左边操作数的结果是0的时候,右边操作数就不再执行。
对于 || 操作符是怎么样呢?我们结合前⾯的代码: if(month == 12 || month==1 || month == 2) 如果month==12,则不用再判断month是否等于1或者2,整个表达式的结果也是1(是冬季)。 所以, || 操作符的左操作数的结果不为0时,就无需执行右操作数。
像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值。
阅读下面代码,写出最后的结果:
cpp
#include <stdio.h>
int main()
{
int i = 0,a= 0,b= 2,c = 3,d= 4;
i = a++ && ++b && d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
上述代码的解释:上述代码考察了逻辑运算符短路的问题。a++为先用后加的自增运算,所以a++为0,逻辑且后面的运算将不会执行。故最后的答案为:a:1 b:2 c:3 d:4
五.switch语句
1.switch语句的介绍
除了 if 语句外,C语言还提供了 switch 语句来实现分支结构。switch 语句是一种特殊形式的if...else 结构,用于判断条件有多个结果的情况。它把多重 的 else if 改成更易用、可读性更好的形式。下面给出switch语句的语法形式:
cpp
switch(表达式0) //需要注意的是:switch后面的表达式0必须是整形表达式
case结果1: //case后面的数字必须是整型常量表达式
表达式1
break;
case结果2
表达式2
break;
.......
default:
表达式n
上述语法形式中,表达式0计算的结果对应不同的case,对应的case执行下面的表达式。如果没有对应的值就执行default语句后的表达式n。
2.if语句和switch语句的对比
题目描述:输入任意一个整数值,计算除3之后的余数
代码实践:
cpp
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if(n%3 == 0)
printf("整除,余数为0\n");
else if(n%3 == 1)
printf("余数是1\n");
else
printf("余数是2\n");
return 0;
}
cpp
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch(n%3)
{
case 0: //case和后面的整型常量表达式之间必须有空格
printf("整除,余数为0\n");
break; //每个case语句结束必须有break,这样才能跳出整个switch语句
case 1:
printf("余数是1\n");
break;
case 2:
printf("余数是2\n");
break;
}
return 0;
}
3.switch语句中的break语句
前面的代码,我们将去掉break语句,来查看代码运行的结果:
cpp
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch(n%3)
{
case 0:
printf("整除,余数为0\n");
case 1:
printf("余数是1\n");
case 2:
printf("余数是2\n");
}
return 0;
}

可以看出上述代码去掉break语句后,本应该只打印:"余数是1"即可,但是代码结果也打印出了:"余数是2" 。
原因是 switch 语句也是分支效果的,只有在 switch 语句中使用 break 才能在跳出 switch 语 句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续往下执行,有可能执行其他 case 语句中的代码,直到遇到 break 语句或者 switch 语句结束。就比如上面的代码就执行了 case 2 中的语句。 所以在 switch 语句中 break 语句是非常重要的,能实现真正的分支效果。当然,break 也不是每个 case 语句都得有,这就得根据实际情况来看了。下面举一个不需要break语句的例子:
题目1描述:输入一个1~7的数字,打印对应的星期几例如: 输入:1输出:星期一;输入:2 输出:星期二;输入:3 输出:星期三 ......
代码实践:
cpp
#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;
}
return 0;
}
题目2描述:输入1~5,输出的是"工作日" 输入6~7,输出"休息日"
代码实践:
cpp
#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;
}
return 0;
}
上述两个代码演示可以看出:switch语句中不一定非得有break语句,在日常生活中,我们可以根据实际需求来决定break语句是否存在?
4.switch语句中的default
在使用 switch 语句的时候,我们经常可能遇到一种情况,比如 switch 后的表达式中的值无法匹配代码中的 case 语句的时候,这时候要不就不做处理,要不就得在 switch 语句中加入default语句。
就比如前面做的打印星期的练习,如果 day 的输入不是1~7的值,如果我们要提示:输入错误。
cpp
#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;
}
5.switch语句中case和default的顺序问题
在 switch 语句中 case 语句和 default 语句有要求顺序吗?default 只能放在最后吗?
其实,在 switch 语句中 case 语句和 default 语句是没有顺序要求的,只要你的顺序是满足实际需求的就可以。不过我们通常是把 default 语句放在最后处理的。
六.while循环
C语言中提供了三种循环语句,分别是while语句、for语句、do while语句,下面我们将一一讲解,先从while循环开始:
1.while语句的语法形式
while(表达式)
语句; //左边语法形式的意思是当表达式为真时,执行语句;执行完之后继续判断表达式是否为真,若为假则跳出循环;若为真则继续执行语句,以此类推...
cpp
#include <stdio.h>
int main()
{
while(1)
printf("hehe\n"); //while后边的条件满⾜,死循环的打印hehe
return 0;
}
上述代码的解释:因为1恒为真,所以一直不间断的打印:"hehe"。
2.while语句的执行流程

上述为while语句执行的流程图,可以看出:while循环先是判断表达式的真假,若为真,则执行语句的程序;若为假,则跳出循环。
3.while循环的代码实践
(1)练习一
题目描述:在屏幕上打印1~10的值
代码实践:
cpp
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
printf("%d ", i);
i = i+1;
}
return 0;
}

上述代码的解释:先定义一个整型变量i,当i小于等于10就进入while循环,每次循环i自增1。当i自增到11时,循环终止。于是上述代码就打印出了1-10的数字。
(2)练习二
题目描述:输入⼀个正的整数,逆序打印这个整数的每⼀位
例如: 输入:1234,输出:4321
输入: 521,输出:125
代码实践:
cpp
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
while(n)
{
printf("%d ", n%10); //一个数对10求余数是该数的个位上的数字
n /= 10; //每次将该数自除以10,可以少去该数的最低位
}
return 0;
}
上述代码的解释:定义一个整型变量,用于接收键盘输入的值。如果输入的值为非0情况下,就进入while循环,打印n%10这个数,每次打印完之后n自除以10。以此类推就打印出了数字的逆序。
七.for循环
1.for语句的语法形式
for(语句1;语句2;语句3)
语句4; //语句1是循环变量的初始化,语句2是循环结束条件的判断,语句3是循环变量的调整。
2.for语句的执行流程

上述为for循环语句执行的流程图:先进行语句1:循环变量的初始化;然后进行语句2:循环进行的判断语句,判断是否满足进入循环的条件;下一步执行语句4;执行结束后下一步执行语句3:循环变量的调整。调整结束后,执行语句2进行循环条件的判断,如果满足条件就执行语句2。以此类推.....
所以可以得出for循环执行的顺序是:语句1->语句2->语句4->语句3->语句2->语句4->语句3->语句2->语句4->语句3......
3.for循环的代码实践
(1)练习一
题目描述:在屏幕上打印1-10的数字
代码实践:
cpp
#include <stdio.h>
int main()
{
int i = 0;
for(i=1; i<=10; i++)
{
printf("%d ", i);
}
return 0;
}

上述代码的解释:先定义一个循环变量i,然后当i小于等于10,进入for循环内,然后执行循环语句打印i的值,打印完成后i自增1。然后判断i是否小于等于10,若为真,则进入循环;若为假,则跳出循环。以此类推就可以在屏幕上打印出1-10的数字了。
(2) 练习二
题目描述:计算1~100之间3的倍数的数字之和
代码实践:
cpp
#include <stdio.h>
int main()
{
int i = 0;
int sum = 0;
for(i=1; i<=100; i++)
{
if(i % 3 == 0)
sum += i;
}
printf("%d\n", sum);
return 0;
}
上述代码的解释:先定义了循环变量i和整型变量sum,分别用于进入循环和累计求和。然后利用循环遍历1-100所有的数字,然后用if语句判断是否是3的倍数,如果是就累加到sum上,最后得到的sum就是结果。但是代码不够简便,我们可以直接遍历3的倍数,直接进行累加,这样就可以省去判断的代码。
代码优化:
cpp
#include <stdio.h>
int main()
{
int i = 0;
int sum = 0;
for(i=3; i<=100; i+=3)
{
sum += i;
}
printf("%d\n", sum);
return 0;
}
4.while循环和for循环的区别
比较:for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分非常集中,便于代码的维护,而如果代码较多的时候,while 循环的三个部分就比较分散,所以从形式上 for 循环要更优一些。
八.do while循环
1.do while语句的语法形式
在三种循环中,do while循环是用的最少的一个循环,它的语法形式如下:
do
语句;
while(表达式); //左边语法形式的意思是先执行一次语句,然后判断表达式是否为真,若为真则继续执行语句;如果为假,就终止循环。
2.do while语句的执行流程

上述do while语句的执行流程可以得出:do while语句不论条件是否满足循环条件,必执行一次循环语句,执行完之后,才对循环条件进行判断,条件为真则继续执行;反之,终止循环。 所以在 do while 语句中循环体是至少执行一次的,这是 do while 循环比较特殊的地方。
3.do while循环的代码实践
(1)练习一
题目描述:在屏幕上打印1-10的数字
代码实践:
cpp
#include <stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}

上述代码的解释:先定义一个循环变量i,然后执行循环语句:打印i的值,打印完成之后,i自增1,下来进入循环条件的判断,判断为真,则继续执行循环语句;判断为假,则循环终止。以此类推就可以在屏幕上打印出1-10的数字了。
(2)练习二
题目描述:输入一个正整数,计算这个整数是几位数?
例如: 输入:1234 ;输出:4
输入:12 ; 输出:2
代码实践:
cpp
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int cnt = 0;
do
{
cnt++;
n = n / 10;
}
while (n);
printf("%d\n", cnt);
return 0;
}
上述代码的解释:先定义一个整型变量n表示键盘输入的数字。再定义一个变量用于表示该数的位数。下来进入do while 循环先执行循环语句,将cnt变量自增1。然后对n自除以10,从而去掉n的最低位。以此类推当n变成0时,循环终止,得到的cnt就是键盘输入的数字位数。
九.break和continue语句
在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这是非常常见的现象。C语言中提供了 break 和 continue 两个关键字,就是应用到循环中的。
• break 的作用是用于永久的终止循环,只要 break 被执行,直接就会跳出循环,继续往后执 行。
• continue 的作用是跳过本次循环中continue 后边的代码,在for 循环和 while 循环中有所差异的。
1.while循环中的break和continue语句
(1)break语句
cpp
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
break;//当i等于5后,就执⾏break,循环就终⽌了
printf("%d ", i);
i = i+1;
}
return 0;
}

上述代码的解释:打印了1,2,3,4后,当i等于5的时候,循环在 break 的地方终止,不再打印,不再循环。所以 break 的作用就是永久的终止循环,只要 break 被执行, break 外的第⼀层循环就终止了。 那以后我们在循环中,想在某种条件下终止循环,则可以使用break 来完成我们想要的效果。
(2)continue语句
cpp
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
continue;
//当i等于5后,就执⾏continue,直接跳过continue的代码,去循环的判断的地⽅
//因为这⾥跳过了i = i+1,所以i⼀直为5,程序陷⼊和死循环
printf("%d ", i);
i = i+1;
}
return 0;
}
上述代码的执行结果为1 2 3 4,然后程序就陷入了死循环,光标一直在闪烁,但是没有任何实质性的操作
上述代码的解释:continue 可以帮助我们跳过某一次循环 continue 后边的代码,直接到循环的判断部分,进行下一次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成死循环。
2.for循环中的break和continue语句
(1)break语句
cpp
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
break;
printf("%d ", i);
}
return 0;
}

上述代码的解释: for 循环中的 break 也是用于终止循环的,不管循环还需要循环多少次,只要执行到了 break语句 ,循环就彻底终止。
(2)continue语句
cpp
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
continue;//这⾥continue跳过了后边的打印,来到了i++的调整部分
printf("%d ", i);
}
return 0;
}

上述代码的解释:在 for 循环中 continue 的作用是跳过本次循环中 continue 后的代码,直接去到循环的调整部分。未来当某个条件发生的时候,本次循环无需再执行后续某些操作的时候,就可以使用 continue 语句来实现。
(3) 两种循环continue的区别

上述图片可以看出来:while循环的continue直接跳到循环条件的判断表达式位置;而for循环的continue将循环跳到循环变量调整的表达式位置。
3.do while循环中的break和continue语句
do while循环中的break和continue语句和while循环的一模一样 ,下面给出两个代码:
cpp
#include <stdio.h>
int main()
{
int i = 1;
do
{
if(i == 5)
break;
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}

上述代码的解释:当i等于5时,不打印5,跳出整个循环。
cpp
#include <stdio.h>
int main()
{
int i = 1;
do
{
if(i == 5)
continue;
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
上述代码的解释:当i等于5时,跳出本次循环到循环条件的判断表达式位置处。因此也跳过了循环变量的自增,导致上述代码的执行结果为1 2 3 4,然后程序就陷入了死循环,光标一直在闪烁,但是没有任何实质性的操作。
这里需要注意的是:将循环变量自增代码写在continue可以规避上述情况。
十.循环的嵌套
题目描述:找出100~200之间的素数,并打印在屏幕上。
代码实践:
cpp
#include <stdio.h>
int main()
{
int i = 0;
//循环产⽣100~200的数字
for(i=100; i<=200; i++)
{
//判断i是否为素数
//循环产⽣2~i-1之间的数字
int j = 0;
int flag = 1; //假设i是素数
for(j=2; j<i; j++)
{
if(i % j == 0)
{
flag = 0;
break;
}
}
if(flag == 1)
printf("%d ", i);
}
return 0;
}
上述代码的解释:素数是只能被1和它本身整除的数相当于质数。先定义一个循环变量i,然后遍历100-200之间的数定为i,得到100-200之间的数字之后,然后遍历从2到该数之间的所有数定为j,当数字i能被j中的一个数整除时,就说明:该数不是素数,跳出此次循环。进行下一个数i的判断,以此类推......
十一.go to语句
C语言提供了一种非常特别的语法,就是 goto 语句和跳转标号,goto 语句可以实现在同一个函数内跳转到设置好的标号处。
代码实践:
cpp
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next;
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}

上述代码的解释:先打印hehe然后执行go to语句,跳到next的位置打印:"跳过了haha的打印"
goto 语句如果使用的不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,所以我们的建议是能不用尽量不去使用;但是 goto 语句也不是⼀无是处,在多层循环的代码中,如果想快速跳出使用 goto 就非常的方便。
cpp
for(...)
{
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
}
error:
.........
本来 for 循环想提前退出得使用break ,但是一个 break 只能跳出一层 for 循环,如果3层循环嵌套就得使用3个 break 才能跳出循环,所以在这种情况下我们使用 goto 语句就会更加的快捷。