C语言参悟-循环控制
- 一、循环综述
- 1. C语言的循环概念
- 2. 循环条件
- 3. 循环单元
- 4. 循环中断
- 二、for 循环
- 三、while 循环
- 四、do while 循环
一、循环综述
下面只是我的对于C语言的认识拙见,可以多多提出批评建议😄
计算机的诞生很大程度上就是为了来进行重复性的某些工作,就像工厂里面的流水线一样,都是在重复的循环做某一件事情,只要涉及到工作,就需要流程来控制,流程里面一个很重要的概念就是循环,循环的诞生就是解决实际工作中重复性的做一些工作。计算机的我记得就是遵循图灵机模式,很类似流水线的工作。计算机的CPU总是遵循着按照一定的流程运行的。
对于C语言作为一个编程语言也是遵循这样的流程,体现在源码就是代码从上往下执行:
也就是在CPU运行这个编译好的程序的代码的时候也是 按照
- -> a = a + 1;
-> b = a + 1;
-> i = a + b;
-> return 0;
上面的顺序执行的。
#include <stdio.h>
int main()
{
int i = 0, a = 1, b = 2;
a = a + 1;
b = a + 1;
i = a + b;
return 0;
}
编程语言的灵活性很大程度上就是体现在流程控制,流程控制里面最重要的也就是 重复执行语句(循环)、满足条件执行语句(分支)。
1. C语言的循环概念
C语言里面对于流程控制里面的循环重复提供了好几种方案,每一种方案都是具有特定的工作场景的。
C语言里面提供了三种循环:
- for 循环
- while 循环
- do while 循环
基本流程都是像下面这种
循环的基本结构:
- 循环条件
其实就是类似 if 里面条件计算的值 就是 0 1 控制 - 循环单元
就是循环里面的语句 - 循环中断
就是 break、continue 这种控制的。一般不会用 goto (比较危险)、Return 有时候也会使用的。
我们可以看看基本的 这个 循环的语法
//for 循环
for(循环条件)
{
循环单元-(包含 循环中断-可选)
}
//while 循环
while(循环条件)
{
循环单元-(包含 循环中断-可选)
}
//do while() 循环
do
{
循环单元-(包含 循环中断-可选)
}while(循环条件)
循环也是受控制的,并不是说循环会处于一直循环、一直不循环、循环了就不可以断、跳不过循环里面的某次循环单元 的状态。受控制的话就是 循环条件 和 循环中断:循环条件其实就是控制循环的起始、中断之类的;循环中断其实就是用的 continue;break 来弄。
对于 一直循环、一直不循环 问题状态基本上是 开始的循环条件 问题
对于 循环了就不可以断、跳不过循环里面的某次循环单元 问题状态 就是 循环中断 问题
2. 循环条件
循环的条件其实就是用的 1(非0) 和 0 表示的循环的起止。C语言就是用的就是 非0 表示 1,但是我一般还是用 的 1 来区分 0。只要一个式子是能计算出 0 或 非0 的式子就能充当循环条件的。 void 类型是不能充当循环条件的哈。
当然哈进入循环的条件肯定也是 1(非0),要退出循环条件的时候就是把循环条件的值置为 0 就结束循环了。
C语言的语句总是会计算出一个值的,之前是没有 布尔值,好像 C99 标准就是 有 _Bool 当 true 和 false 使用啦。
⭕️ 注意:如果循环条件一直是 1 的话,就会一直处于循环条件,就是死循环; 死循环有好有坏。死循环有时候很有用,有时候也是我们需要避免的。不想死循环的话,一定要记得让退出条件有效。
死循环条件有很多的 应用场景:
- socket 持续监听、发送、接收数据。
- 消息事件系统。
- 服务器持续运行
循环条件的例子:
循环条件的例子其实就是 能够产生 0 或者非 0 的式子就可以的。当然,记住产生这个结果的式子的时候,这个式子可能已经执行了某些功能,或着已经获取到了某些东西。 并不是单纯的作为了一个结果标志。
-
直接式
直接写值。 -
逻辑比较式
就是基于逻辑运算符 >、 <、 >= 、<=、!=、==、&&、|| 计算出来的值。 -
函数返回式
就是把函数的返回值当成一个标志来判断 -
计算式
就是使用了 逻辑运算、算术运算、函数返回运算等组合的计算,这个是最灵活的。
下面就以 while 的循环条件举例子
//直接式-真值
while(1)
while(2)
while(-13) //这个也是 真值哦!
while("") //这个也是 真值哦!
//直接式-假值
while(0)
while('\0')
while(NULL)
//逻辑比较式-真值
while(1 != 2)
while(0 == 0)
while(1 == 1) //别写成了 赋值号 =
while(1 > -12)
while('-' >= '+') // '-' 的ASCII值是 45; '+' 的ASCII值是 43
while('-' >= 44) //用的就是值比较的
while(45 >= 40 && 45 <= 50) //逻辑合并比较
while(1 > 0 || 1 < 0) //这个也是真值哦!C语言使用 || 判断时候是有逻辑短路性的,
//只有 || 多个条件中,重左到右只有有一个真值就执行啦,
// 但 && 是两个条件必须同时满足,就不具有逻辑短路
//逻辑比较式-假值
while(1 >= 2)
while('\0' > '+')
while(NULL == 1)
//函数式-真值
char m_ch;
//这个就是函数式子,这个执行了两个语句,第一个是获取字符,第二个是对读取的字符数比较
while(m_ch=getchar()) != EOF)
{
//从控制台读取数据
}
//这是一个函数原型:判断是否大写
int isCapitalized(char ch);
char ch = 'A';
while(isCapitalized(ch))
{
//这里就可以判断是否大写字母
// ch = ...语句之类
}
//计算式-真值
char m_ch = '-';
// 这个就是函数式子,这个执行了三个语句,
// 第一步是从控制台获取字符,
// 第二步是对读取的字符数比较是否是读正确没有
// 第三步是判断读取的字符是否是 '&'
while(m_ch=getchar()) != EOF && m_ch != '&')
{
//从控制台读取数据
}
//注意这个下面的写法和上面就是位置不对,
// 这个功能就完全不一样的哦,这个就是自己写代码的问题了
// 这里执行了三个语句,
// 第一步判断读取上一次的字符是否是 '&' :如果没初始化m_ch ,估计是有问题的,
// 第二步是从控制台获取字符,
// 第三步是对读取的字符数比较是否是读正确没有
while(m_ch != '&' && m_ch=getchar()) != EOF)
{
//.....
}
3. 循环单元
循环单元其实就是需要我们循环去执行的代码。
在C语言中,这个循环单元其实是当成一个函数来运行的。那就需要记住在这个循环单元里面定义的新变量是无法在这个循环外面获取到的。而且每次循环结束的时候这些在循环里面定义新的变量都是被释放掉了;第二次新的循环的时候又会重新申请新变量的。这个就是完全和函数的内存分配机制是一样的。
这里面有时候就需要 修改循环单元外的变量,这是肯定允许的哈。也是实际工作中需要使用的。
这里面就是写功能代码的,没啥特别需要注意的。
4. 循环中断
这里的循环中断,我一般也会用到 break、continue、return 这种控制的。
我对于这个的理解就是上面的功能就是解决在循环时出现 循环了就不可以断、跳不过循环里面的某次循环单元语句 的问题。
- break :就是中断结束这次包含break 的循环。但如果这个循环的外面还有循环时,这个break只对当前循环区域起作用。
- continue:不中断结束 这次包含continue 的循环。只是在这个循环单元里面continue后面的语句就不执行了,和break的一样区域就开始下一次循环。
- return:不仅是中断结束循环,而且是直接返回去了,这个作用区域是不管区域的。return 了 就直接函数结束了。在循环外后面的语句都不执行,这个有时候也会用到。
这里是 break的作用范围
for(int i = 1; i < 5; i++)
{
for(int j = 6; j < 10; j++)
{
qDebug()<< i * 10 + j;
if(j == 7 )
{
//这里只会退出 j 的循环
break;
}
}
if(i == 2)
{
//这里就是退出i 的 循环
break;
}
}
//这个的输出就是
16 17 26 27
这里是break和continue的区别
for(int j = 6; j < 10; j++)
{
if(j == 7 )
{
break;
}
qDebug()<< j;
}
//输出 6
for(int j = 6; j < 10; j++)
{
if(j == 7 )
{
continue;
}
qDebug()<< j;
}
//输出 6 8 9
这里是break和continue和return的区别
for(int j = 6; j < 10; j++)
{
if(j == 7)
return 0;
if(j == 8 )
{
break;
}
qDebug()<< j;
}
for(int j = 6; j < 10; j++)
{
if(j == 7 )
{
continue;
}
qDebug()<< j;
}
//输出 6
我在实际使用的时候 经常会使用到 continue ,一个场景就是 对循环的一个语句需要判断,判断就不继续执行了,这里是因为没办法使用 if else 那种多分支判断,这就需要用continue,就不用吧所有的 if 全部执行,就提高了效率。
while(条件)
{
if(....)
{
...
continue;
}
if(....)
{
...
continue;
}
....
if(....)
{
...
continue;
}
}