深圳市华胄科技有限公司 >> MCU专题 >> 单片机编程


单片机c语言,10小时学会C 语言 (六)



提交者 电子007  在  2008-3-17 14:49:58 

上一篇 下一篇
单片机c语言,10小时学会C 语言 (六)


第六章 循环与自动重复


前一章,已经用了 for 循环来写程序,让程序依需求重复执行某些程序代码。在 C 中有许多种循环,本章就以 for 循环为主,介绍循环设计的技巧。


◎ for 叙述


○ for 叙述的格式如下:
┌───────────────────────────────────────────────────┐
│for ( 指令一 ; 条件测试 ; 指令二 ) │
│{ 指令群 } │
└───────────────────────────────────────────────────┘
注意:在 for 后面有对小括号,小括号里面的东西用分号隔成三个部份,这二个分隔用的分号绝对不可以省略掉。


○ for 叙述的意义:
┌────────────────────────────────────────────────┐
│1.先执行「指令一」。 │
│2.测试看看「条件测试」是否成立?如果成立,则执行 │
│ { 指令群 };否则,结束自动重复的动作。 │
│3.在执行完 { 指令群 } 后,执行「指令二」,然后回到 2。│
└────────────────────────────────────────────────┘


○ for 叙述流程图:

┌─────┴───┐
│指 令 一│
└─────┬───┘

/\
/ \
不成立 / 条件 \ ←───────┐
┌─────── \ 测试 / │
│ \ / ┌────┴────┐
│ \/ │指 令 二│
│ 成立↓ └───┬─────┘
│ ┌──────┴──┐ ↑
│ │指 令 群├──────────┘
│ └─────────┘

└─────────────┐


在这里,指令一及指令二都是单一指令,如果你要作多项设定,那就要用到上一章最后所讲的「逗号运算子」,可以将多个指令写在一起。


○ 常见 for 叙述的用法:
┌──────────────────────────────────────────────────────┐
│for ( i = 0 ; i < 100 ; i = i+1 ) │
│ printf("i = %3d\n", i ); │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│for ( i = 0 , j = 0 ; i < 100 ; i = i+1 , j = j+2 ) │
│ printf("i = %3d j = %3d\n", i, j ); │
└──────────────────────────────────────────────────────┘


○ for 叙述常用的格式:
┌─────────────────────────────────────────────────────┐
│for ( 初值设定 ; 条件测试 ; 变化 ) │
│{ 指令群 } │
└─────────────────────────────────────────────────────┘


○ for 叙述常用格式的意义:
┌───────────────────────────────────────────────┐
│1.首先依「初值设定」的要求,设定你所指定变量的值。 │
│2.测试看看「条件测试」是否成立?如果成立,则执行 │
│ { 指令群 };否则,结束自动重复的动作。 │
│3.在执行完 { 指令群 } 后,按照「变化」的要求,改变指定│
│ 变量的值,然后回到 2 。 │
└────────────────────────────────────────────────┘


○ for 叙述常用格式的流程图:

┌─────┴───┐
│ 初值设定 │
└─────┬───┘

/\
/ \
不成立 / 条件 \ ←───────┐
┌─────── \ 测试 / │
│ \ / ┌─────┴───┐
│ \/ │ 变 化 │
│ 成立↓ └────┬────┘
│ ┌─────┴───┐ ↑
│ │指 令 群├───────────┘
│ └─────────┘

└─────────────┐


○ 省略的 for 叙述:
┌───────────────────────────────────────────────────┐
│for ( 指令一 ; 条件测试 ; 指令二 ) │
│{ 指令群 } │
└───────────────────────────────────────────────────┘
在 for 叙述中,指令一、条件测试、指令二以及指令群这四者都可以省略,
△ 省略指令一:以常用格式来说,就是不做初值设定。
初值可在 for 之前设定,或者不用做初值设定。
△ 省略条件测试:表示不做条件测试,重复执行 { 指令群 }。
我们通常称这种循环为「无穷循环」。
△ 省略指令二:以常用格式来说,就是不做变量数值的改变。
变量数值可以在指令群中改变。
△ 省略指令群:表示空循环,可用于时间延迟(delay)。
若连大括号都要省略,则要补上分号 ( ; ) 表示空指令。
for 叙述括号内的指令是可以省的,但是分隔用的分号 ( ; ) 则不能省。


以下是课本的范例:秀出 ASCII 码及相对应的字符。
┌────────────────────────────────────────────────────────────────┐
│ascii.c │
├────────────────────────────────────────────────────────────────┤
1│#include /* 宣告 printf() 的原型 */ │
2│void main(void) │
3│{ │
4│ int i; │
5│ │
6│ for( i = 32 ; i < 256 ; i = i+1 ) │
7│ printf("%3d=%c\t", i, i ); │
8│} │
├────────────────────────────────────────────────────────────────┤
│ 32= 33=! 34=" 35=# 36=$ 37=% 38=& 39=' ...
│ 42=* 43=+ 44=, 45=- 46=. 47=/ 48=0 49=1 ...
│ 52=4 53=5 54=6 55=7 56=8 57=9 58=: 59=; ...
│... ...
│252=* 253=* 254=* 255= │
└────────────────────────────────────────────────────────────────┘
for( i = 32 ; i < 256 ; i = i+1 )
======== ======== =========
初值设定 条件测试 变化


在 C 语言中,我们通常会把 i = i + 1 这种变量递增写成 i++ 。同样的,变量递减写成 i-- 表示 i = i - 1 。


如果递增或递减的数值不是1,则写成i+=2表示i=i+2或i-=2表示i=i-2。


注意,在这里的+=或-=不可以分开。同样的,乘除法也有相同的用法,如 i *= 2 表示 i = i * 2 、 i /= 2 表示 i = i / 2 。


以下的范例用来计算 n! 的值。
┌────────────────────────────────────────────────────────────────┐
│n!.c │
├────────────────────────────────────────────────────────────────┤
1│#include /* 宣告 printf(),scanf() 的原型 */ │
2│void main(void) │
3│{ │
4│ long fact; │
5│ int n; │
6│ │
7│ printf("Enter the value of n to compute n! : "); │
8│ scanf("%d", &n ); │
9│ printf("%d! = %d", n, n ); │
10│ fact = n; │
11│ for( n = n-1 ; n >0 ; n-- ) │
12│ { │
13│ fact *= n; │
14│ printf("x%d", n); │
15│ } │
16│ printf(" = %ld", fact); │
17│} │
├────────────────────────────────────────────────────────────────┤
│Enter the value of n to compute n! : 5 │
│n! = 5x4x3x2x1 = 120 │
└────────────────────────────────────────────────────────────────┘


n 阶乘的定义是 n! = n * (n-1) * (n-2) * ... * 2 * 1


在上面的程序中以 fact 这个变量来存 n 阶乘的数值。此例来说,输入的数值为 5 ,所以第 9 行的 n 为 5 。第 10 行 fact = n; 设定 fact = 5 。再来进入循环,先设定 n 为 n-1 也就是 4 ,因为 n 阶乘下一个是要乘 n-1 ,第 13 行 fact *= n 也就是 fact = fact * n ,因为每次循环 n 的值都会减 1 ,如此,就达到阶乘的效果。以下是 fact 及 n 在每次循环的数值:
┌─────────┬────────────┬────┬──────────────────────┐
│ 时 刻 │ fact 值 │n 值│ 印 出 效 果 │
├─────────┼────────────┼────┼──────────────────────┤
│进入循环前│ 5 │ 5 │5! = 5 │
├─────────┼────────────┼────┼──────────────────────┤
│n 初值设定│ 5 │ 4 │5! = 5 │
├─────────┼────────────┼────┼──────────────────────┤
│第 1 圈后 │ 5*4 │ 4 │5! = 5x4 │
├─────────┼────────────┼────┼──────────────────────┤
│第 2 圈后 │ 5*4*3 │ 3 │5! = 5x4x3 │
├─────────┼────────────┼────┼──────────────────────┤
│第 3 圈后 │ 5*4*3*2 │ 2 │5! = 5x4x3x2 │
├─────────┼────────────┼────┼──────────────────────┤
│第 4 圈后 │ 5*4*3*2*1 │ 1 │5! = 5x4x3x2x1 │
├─────────┼────────────┼────┼──────────────────────┤
│离开循环后│ 5*4*3*2*1 │ 1 │5! = 5x4x3x2x1 = 120 │
└─────────┴────────────┴────┴──────────────────────┘


◎ 重复中有重复


在 for 叙述所要重复执行的指令群中,也可以再含有另一个 for 叙述,于是便形成了重复中有重复的情形。一般我们称 for 叙述及所重复的指令群为 for 循环,而这种重复中有重复的情形,便称为巢状(nest)循环。(课本称为套迭式循环)


在使用巢状循环时,最好使用缩排的编辑技巧,让你的程序更好看:
叙述;
...
for( ... ; ... ; ... )
┌────────→{
│ 叙述;
│ ...
│ for( ... ; ... ; ... )
│ ┌──────→{
│ │ 叙述;
│ │ ...
│ └───────}
│ 叙述;
│ ...
└─────────}


同样的技巧可以用在巢状 if 叙述,或其它类似的叙述。


巢状循环可以多层,但是,各个循环之间绝对不可以交叉。以下是正确的巢状循环:
┌──────→ for(...;...;...)
│ {
│┌───────→ for(...;...;...)
││ {
││ ...
│└──────── }
│ ...
│┌───────→ for(...;...;...)
││ {
││ ...
│└──────── }
└────────── }
┌─────────→ for(...;...;...)
│ {
│┌────────→ for(...;...;...)
││ {
││ ...
││┌─────→ for(...;...;...)
│││ {
│││ ...
││└────── }
│└───────── }
│ ...
└──────────── }


以下是不正确的巢状循环:
┌───────────→ ┌──→
│ │
│ ┌─────→ ┌──┼──→
│ │ │ │
└──┼──── │ └───
│ │
└──── └─────


以下的范例:印出九九表
┌────────────────────────────────────────────────────────────────┐
│99.c │
├────────────────────────────────────────────────────────────────┤
1│#include /* 宣告 printf() 的原型 */ │
2│void main(void) │
3│{ │
4│ int i, j; │
5│ │
6│ for( i=1 ; i<=9 ; i++ ) │
7│ { │
8│ for( j=1 ; j<=9 ; j++ ) │
9│ printf("%dx%d=%2d ", j, i, j*i ); │
10│ printf("\n"); │
11│ } │
12│} │
├────────────────────────────────────────────────────────────────┤
│1x1= 1 2x1= 2 3x1= 3 4x1= 4 5x1= 5 6x1= 6 7x1= 7 8x1= 8 9x1= 9 │
│1x2= 2 2x2= 4 3x2= 6 4x2= 8 5x2=10 6x2=12 7x2=14 8x2=16 9x2=18 │
│1x3= 3 2x3= 6 3x3= 9 4x3=12 5x3=15 6x3=18 7x3=21 8x3=24 9x3=27 │
│1x4= 4 2x4= 8 3x4=12 4x4=16 5x4=20 6x4=24 7x4=28 8x4=32 9x4=36 │
│1x5= 5 2x5=10 3x5=15 4x5=20 5x5=25 6x5=30 7x5=35 8x5=40 9x5=45 │
│1x6= 6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36 7x6=42 8x6=48 9x6=54 │
│1x7= 7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49 8x7=56 9x7=63 │
│1x8= 8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64 9x8=72 │
│1x9= 9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81 │
└────────────────────────────────────────────────────────────────┘


九九表是 1 到 9 的两个数相乘,一个是乘数,一个是被乘数,因此,我们需要两个循环, i=1 要乘以 1 到 9 、 i=2 也要乘以 1 到 9 、...,所以要用巢状循环的方式来处理这个问题。第 9 行的 printf("%dx%d=%2d ", j, i, j*i ); 是属于内层循环,也就是在某一个 i 值, j 要由 1 变化到 9 。第 10 行的 printf("\n"); 是属于外层循环,在内层循环执行完之后,就跳下一行。


◎ 跳出循环: break 叙述


有时,我们可能在重复执行到一半时,检测到某个情况发生,而希望提早结束重复的动作,便可以利用 break 叙述。 break 叙述的功能相当单纯,它用来跳出一层的循环。注意!它只能跳出一层循环。如果你使用两层的巢状循环,那么在内层的break 只会跳出内层循环,在外层的 break 才会跳出外层循环。
┌───────→ for(...;...;...) /* 外层循环 开始 */
│ {
│┌──────→ for(...;...;...) /* 内层循环 开始 */
││ {
││ ...
││ if(...) break; /* 跳出内层循环 */
││ ...
│└─────── } /* 内层循环 结束 */
│ ...
│ if(...) break; /* 跳出外层循环 */
│ ...
└───────── } /* 外层循环 结束 */


○ Ctrl + C 或 Ctrl + Break 中断按键


当程序进入无穷循环时,在某些状况下,你可以按下 Ctrl + C 或 Ctrl + Break来中断程序的执行,但是在某些状况下,即使你按下 Ctrl + C 或 Ctrl + Break也没有用,只有重开机才能中断程序执行。所以,在程序中最好能正常结束,例如:使用者按下 q 键或 x 键表示结束程序等等,若你要使用无穷循环,最好能确定用 Ctrl + C 或 Ctrl + Break 可以中断程序。


☆ 其它的循环 ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆


除了 for 以外, C 语言还有 while 循环及 do ... while 循环。


◎ while 循环


○ while 叙述的格式如下:
┌─────────────────────────────────────────────────────┐
│while ( 条件测试 ) │
│{ 指令群 } │
└─────────────────────────────────────────────────────┘


○ while 叙述的意义:
┌────────────────────────────────────────────────────────┐
│1.测试看看「条件测试」是否成立? │
│ 如果成立,则执行{ 指令群 };否则,结束自动重复的动作。 │
│2.执行完{ 指令群 }后,再回到 1 。 │
└────────────────────────────────────────────────────────┘


○ while 叙述流程图:

/\
/ \
不成立 / 条件 \ ←───────┐
┌──────── \ 测试 / │
│ \ / │
│ \/ │
│ 成立↓ │
│ ┌─────┴───┐ │
│ │指 令 群├────────────┘
│ └─────────┘

└─────────────┐


我们可以把 while 循环用 for 循环来表示:
while( i < 10 ) for( ; i<10 ; )
{ {
... ...
} }


◎ do ... while 循环


○ do ... while 叙述的格式如下:
┌──────────────────────────────────────────────────────┐
│do │
│{ │
│ 指令群 │
│} while ( 条件测试 ); │
└──────────────────────────────────────────────────────┘


○ do ... while 叙述的意义:
┌────────────────────────────────────────────────────────┐
│1.先执行{ 指令群 }。 │
│2.测试看看「条件测试」是否成立? │
│ 如果成立,则执行{ 指令群 };否则,结束自动重复的动作。 │
│3.执行完{ 指令群 }后,再回到 2 。 │
└─────────────────────────────────────────────────────────┘


○ do ... while 叙述流程图:

↓←──────┐
┌─────┴───┐ │
│指 令 群│ │
└─────┬───┘ │
↓ │
/\ │
/ \ 成立 │
/ 条件 \ ──────┘
\ 测试 /
\ /
\/
│不成立


while 循环与 do ... while 循环最大的不同点在于:


while 循环要先条件测试,成立才执行指令群,而 do ... while 循环则是先执行指令群,才条件测试,成立再一次执行指令群。



单片机教程,五系列(55讲)电子书全集下载

论坛精选:
■ 单片机c语言,10小时学会C 语言 (一)
第一章 C 语言简介与Turbo C 的使用
■ 单片机c语言,10小时学会C 语言 (二)
第二章 C 程序的结构
■ 单片机c语言,10小时学会C 语言 (三)
第三章 常数与变数
■ 单片机c语言,10小时学会C 语言 (四)
第四章 基本输出入函式
■ 单片机c语言,10小时学会C 语言 (五)
第五章 流程图与抉择指令
■ 单片机c语言,10小时学会C 语言 (六)
第六章 循环与自动重复
■ 单片机c语言,10小时学会C 语言 (七)
第七章 数组与指针
■ 单片机c语言,10小时学会C 语言 (八)
第八章 函数与呼叫
■ 单片机c语言,10小时学会C 语言 (九)
第九章 档案存取

1 楼  提交者:Guest 在 2008-3-18 14:08:26
想看看。
2 楼  提交者:king 在 2008-3-18 15:53:33
ok
3 楼  提交者:浪人 在 2008-3-18 20:53:33
大侠
4 楼  提交者:卫立 在 2008-3-18 22:50:19
卡们
5 楼  提交者:木木林 在 2008-3-19 10:18:09
FFFF
6 楼  提交者:han2002asd 在 2008-3-19 12:38:06
vb 
7 楼  提交者:郭总 在 2008-3-19 13:50:51
大家好
8 楼  提交者:anny2008 在 2008-3-19 16:30:19
9 楼  提交者:Guest 在 2008-3-19 17:53:48
10 楼  提交者:中山盈亮 在 2008-3-20 11:22:13
不错,谢谢
11 楼  提交者:Guest 在 2008-3-20 20:02:07
klkl
12 楼  提交者:goldskin 在 2008-3-20 21:48:21
gan
13 楼  提交者:Guest 在 2008-3-21 8:58:34
14 楼  提交者:梦蝶秋 在 2008-3-21 11:45:30
呵呵
15 楼  提交者:youminbuluo 在 2008-3-21 20:54:17
好累啊啊
16 楼  提交者:高臣 在 2008-3-22 13:18:05
学习
17 楼  提交者:luxs 在 2008-3-22 13:57:46
可以不可以不用回復
18 楼  提交者:liuyiqiangqq 在 2008-3-22 21:52:16
19 楼  提交者:liuyiqiangqq 在 2008-3-22 21:52:19
20 楼  提交者:有点意思 在 2008-3-22 23:43:30
good hao
21 楼  提交者:Guest 在 2008-3-23 0:25:54
22 楼  提交者:Guest 在 2008-3-23 0:26:03
23 楼  提交者:Guest 在 2008-3-23 0:26:19
24 楼  提交者:Guest 在 2008-3-23 0:30:31
25 楼  提交者:Guest 在 2008-3-24 8:58:02
q
26 楼  提交者:有点意思 在 2008-3-26 17:02:04
hao~
27 楼  提交者:dalianshide 在 2008-3-28 0:38:16
sdf
28 楼  提交者:许可 在 2008-3-28 10:59:14
29 楼  提交者:kouxiangtang 在 2008-3-28 12:24:52
好好学习
30 楼  提交者:sjf_5566 在 2008-3-29 11:04:33
回帖是一种美德
上一篇 下一篇
当前第〖1〗页 共有21页 转到第 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21