📄 00000005.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: <A HREF="mailto:ax.bbs@bbs.ee.nthu.edu.tw.">ax.bbs@bbs.ee.nthu.edu.tw.</A> (athena), 信区: test <BR>标 题: 星星流讲座 0020 <BR>发信站: ☆清华电机☆ (Tue May 23 11:20:45 1995) <BR> <BR> <BR>第 4 讲 之 5 基本的流程控制 <BR> Topic: for loop (1) <BR> <BR>我们前面讨论了 while 和 do-while 的回圈,为什麽叫回圈呢?因为在条件 <BR>成立的时候会一直执行重复的程式区块,所以我们叫它回路或回圈。许多回 <BR>圈在执行的时候是以执行的次数做为条件的,比方说: <BR> <BR> i = 0; <BR> while (i < 10) <BR> { <BR> i++; <BR> /* 回圈的剩馀部分,但是不会用到 i,i 只是个计次用的变数 */ <BR> } <BR> <BR>这个时候我们就可以利用 for 回圈来简化上面的程式: <BR> <BR> for (i = 0; i < 10; i++) <BR> { <BR> /* 回圈 */ <BR> } <BR> <BR>for 的用法是这样的: <BR> <BR> for (i = 0; i < 10; i++) <BR> □ ↑ □ <BR> 计次用变数的 回圈执行 计次用变数 <BR> 初始值 条件 每次值的变化 <BR> <BR>在做进一步的深入探讨之前,请你写作一个九九乘法表的程式,它的输出和小 <BR>学生垫板後面的相同。 <BR> <BR>for 回圈最有意思的是计次变数初始值、回圈执行条件及计次变数的变化都可以不 <BR>给,例如: <BR> <BR> for ( ; i > 10; i--) /* 前面已给过 i 的初值了,所以回圈不必再给 */ <BR> for ( ; i > 10; ) /* 回圈中会不规则的变动 i,把 for 当成 while */ <BR> /* 来用,这是因为有人不会用 while :) */ <BR> for ( ; ; ) /* 永不停止的回圈 (无穷回圈 infinite loop) */ <BR> <BR>以上是最常见的三种情形,其他的情形除非你有特别巧妙的设计,否则该用 while <BR>的时候还是用 while 来做比较清晰易懂。 <BR> <BR>/* shellsort.c */ <BR>#include <stdio.h> <BR> <BR>void shellsort (int v[], int n) /* v[]: array to sort */ <BR>{ /* n: # elements in array */ <BR> int gap, i, j, temp; <BR> <BR> for (gap = n / 2; gap > 0; gap /= 2) <BR> { <BR> printf ("shell sort gap %d\n", gap); <BR> for (i = gap; i < n; i++) <BR> { <BR> printf ("shell sort level %d\n", i); <BR> for (j = i - gap; j >= 0 && v[j] > v[j + gap]; j -= gap) <BR> { <BR> temp = v[j]; <BR> v[j] = v[j + gap]; <BR> v[j + gap] = temp; <BR> } <BR> } <BR> } <BR>} <BR> <BR>上面的程式是欣赏用的,我们的目的并不在讲 shell sort,而是要和各位谈谈如何 <BR>写出「乾净」的程式码。首先请看到上面程式里的大括号都是上下对齐的,大括号 <BR>内的东西向内缩四格,为什麽要这样做呢?看看以下错误的示□你就知道了: <BR> <BR> for (i = 0; i < 10; i++) { <BR> /* .... */ <BR> } <BR> <BR>第一个不好的习惯是上下的大括号不对齐,像 vi 或 jove 这种编辑器会自动替你 <BR>match 括号,提醒你是否有括号不对称的情形,这当然是很好用的工具。但是如果 <BR>我们现在用的是像 PE2 这种不会替你对括号的编辑器,而你自己又不把括号对齐 <BR>的话,那麽可以预见的是你常常会得到这个错误讯息: <BR> <BR> parse error at end of input <BR> <BR>第二个不好的习惯是程式码不缩排,例如: <BR> <BR> for(gap=n/2;gap>0;gap/=2) <BR> { <BR> printf("shell sort gap %d\n",gap); <BR> for(i=gap;i<n;i++) <BR> { <BR> printf("shell sort level %d\n",i); <BR> for(j=i-gap;j>=0 && v[j]>v[j+gap];j-=gap) <BR> { <BR> temp=v[j]; <BR> v[j]=v[j+gap]; <BR> v[j+gap]=temp; <BR> } <BR> } <BR> } <BR> <BR>所有的码挤成一堆,一点层次感也没有,层次感除了美观之外,它其实有重要的功 <BR>用,在像上面的多重回圈里我们要很用力的看才能看出它在干什麽,而不能如前面 <BR>的 shellsort.c 那麽一目了然。程式码易读的最大好处是缩短除错的时间,减少 <BR>维护程式的成本。 <BR> <BR>至於运算元 (operator) 前後的空白,例如 i = j + 4; 等等,笔者个人是模仿 <BR>Quick BASIC 的风格,如果是单元运算元 (unitary operator) 就不加空白,如: <BR>i++; ,二元运算元 (binary operator) 则前後加空白,如:i = j;。左小括号 ( <BR>前面一定加空白,逗号 , 後面也一定加空白。在 C 语言圣经 K&R 的版本里他们分 <BR>的更细,函数的左小括号前头没有空白,非函数的左小括号前头有空白,例如: <BR> <BR> printf("Hello, world!\n"); /* 函数 */ <BR> for (i = 1; i < 10; i++) <BR> <BR>笔者因为很喜欢按大大的 space 键听它叩叩的声音,所以左括号前一律加空白 :) <BR>初学者常常因为懒惰而吃掉不少空白,套句补习班常用的广告词:今日不做,明日 <BR>後悔。别因一时的懒惰种下明日的苦果,什麽苦果?等你程式写到上千行你就知道了。 <BR> <BR>-- <BR>本文原作者为徐振家,原作刊载於星星神教总坛 ☆清华电机☆ test 板。 <BR>你可以以电子文件的形式将本文自由流传於台湾学术网路,但必须包含此版权声明。 <BR>原作者依中华民国著作权法之规定,享有本文之著作权,请勿抄袭以免触法。 <BR>未经授权任何人不得以任何形式对本文做任何修改及商业上之应用。 <BR>其他网路的转载或其他用途的应用,请先知会作者,并取得其同意。 <BR>对本文有任何疑问或意见请 mail 给 <A HREF="mailto:ax.bbs@bbs.ee.nthu.edu.tw,谢谢。">ax.bbs@bbs.ee.nthu.edu.tw,谢谢。</A> <BR> <BR> <BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -