循环语句在单片机编程应用中是必不可少的一种语句结构,c语言是一种顺序执行语言,如果没有循环语句,c语言会根据程序指针地址的增加一直向下执行,如果没有循环语句加以干涉,加上单片机程序存储空间一般都不大,很容易就会出现程序指针越界的错误。
使用循环可以多次重复地执行多条语句,这里的“多条语句”称为循环体。在C语言中,可以使用三种循环,分别是:while、do...while和for。
While循环语句结构
while(表达式)
{
语句;
}
while 表达式是顶部判断的循环,先计算循环条件(while表达式)。如果为真,则执行循环体语句,然后再次计算循环条件。如果循环条件为假,程序跳过循环体,而去执行循环体后面的语句。从语法上讲,循环体只有一条循环条件。如果需要执行多条循环条件综合判断,可以使用运算方式将它们组合在一起,相关知识后续章节再做介绍,
举个简单的例子,在单片机应用程序开发中,我们都知道main函数是必不可少的,编译器通过main函数来给整个程序定位运行的起始flash地址(单片机应用code,除非用户特别指定,否则应用程序并不是一定从flash的00地址开始执行code的,这点大家需要注意,后续也会有介绍)。而main函数中,最重要也是必不可少的就是while循环语句,而且是应用code中的死循环,我们希望它永远不要跳出去的循环体(原因上面也已经简单介绍了,如果跳出循环,程序执行就有程序指针越界的风险)。
如上例子,就是典型的while死循环的用法,因为其循环判断条件直接就是常数1,也就是真,所以它会一直循环下去。
再举个例子,单片机中一般采用IO口来读取按键的状态(硬件如上图),需要实现的是按键每按下一次,自定义变量seft_count值自加1,直到按键按下10次为止。
for循环语句结构
for循环第一种用法
for(表达式1;表达式2;表达式3)
{
语句;
}
在一个典型的 for 循环中,在循环体判断条件有三个动作需要执行:
(1) 表达式 1:判断条件中变量的初始化
只计算一次。在计算其他循环判断表达式之前,先计算一次,以进行必要的初始化,后面不再计算它。
(2) 表达式 2:控制表达式
每轮循环前都要计算控制表达式,以判断是否需要继续本轮循环。当控制表达式的结果为假,结束循环。
(3) 表达式 3:调节器(计算规则)
调节器(例如计数器自增)在每轮循环结束后且表达式 2 计算前执行。即,在运行了调节器后,执行表达式 2,以进行判断。 2 计算前执行。即,在运行了调节器后,执行表达式 2,以进行判断。
初学者看起来似乎有点晕,没关系,我们举个简单的例子。
上述while举例中出现了一个delay_1ms的延时函数,如果我们对延时时间的精度要求没有那么精确的话,那么delay_1ms的延时函数可以采用for循环的方式来编写。
for循环第二种用法
for(;;)
{
语句;
}
如果没有控制表达式,则表示循环条件始终是 true,也就是说,这定义了一个死循环。
此时for循环的作用就跟while(1)一样,不作累述。
for循环第三种用法
for(;表达式2;)
{
语句;
}
此时for 循环,既没有初始化表达式1,也没有调节器表达式3,它与 while(表达式)语句含义是等效的,所以使用方法可以参照上述while(表达式)的用法。
do…while循环语句结构
do
{
语句;
}while(表达式)
do...while 循环是一种底部判断的循环,在判断条件表达式被第一次计算之前,循环体语句会首先被执行一次。与 while 和 for 循环不同,do...while 循环会确保循环体语句至少执行一次。如果表达式判断的值为真,那么另一次循环就会继续;如果是假,则循环结束。
需要说明的是,相对于while/for语句来说,do…while语句在常规程序中应用不多,但是有一种应用却是很有用,那就是采用do语句while(0)的方式来实现带复杂运算的宏定义。对于初学者来说,暂时可以推后去理解,有兴趣的话可以令开章节再讨论。