Linux 版 (精华区)

发信人: netiscpu (夜☆星光点点☆), 信区: Linux
标  题: ◇ 星星流讲座 0020
发信站: 紫 丁 香 (Sun Nov  8 18:29:23 1998), 转信


寄信人: guest.bbs@hgluo.hust.edu.cn 
标  题: ◇ 星星流讲座 0020
发信站: 华南理工大学 BBS木棉站
日  期: Thu Feb 20 14:45:04 1997

发信人: ax.bbs@bbs.ee.nthu.edu.tw. (athena), 信区: test
标  题: 星星流讲座 0020
发信站: ☆清华电机☆ (Tue May 23 11:20:45 1995)


;35m第 4 讲 之 5            基本的流程控制
                        Topic: for loop (1)m

我们前面讨论了 while 和 do-while 的回圈,为什麽叫回圈呢?因为在条件
成立的时候会一直执行重复的程式区块,所以我们叫它回路或回圈。许多回
圈在执行的时候是以m执行的次数0m做为条件的,比方说:

        i = 0;
        while (i < 10)
        {
            i++;
            /* 回圈的剩馀部分,但是不会用到 i,i 只是个计次用的变数 */
        }

这个时候我们就可以利用 for 回圈来简化上面的程式:

        for (i = 0; i < 10; i++)
        {
            /* 回圈 */
        }

for 的用法是这样的:

                for (i = 0; i < 10; i++)
                     □       ↑       □
             计次用变数的   回圈执行    计次用变数
                初始值      条件        每次值的变化

在做进一步的深入探讨之前,请你写作一个九九乘法表的程式,它的输出和小
学生垫板後面的相同。

for 回圈最有意思的是计次变数初始值、回圈执行条件及计次变数的变化都可以不
给,例如:

        for ( ; i > 10; i--)    /* 前面已给过 i 的初值了,所以回圈不必再给 */
        for ( ; i > 10; )       /* 回圈中会不规则的变动 i,把 for 当成 while */
                                /*   来用,这是因为有人不会用 while :) */
        for ( ; ; )             /* 永不停止的回圈 (无穷回圈 infinite loop) */

以上是最常见的三种情形,其他的情形除非你有特别巧妙的设计,否则该用 while
的时候还是用 while 来做比较清晰易懂。

/* shellsort.c */
#include <stdio.h>

void shellsort (int v[], int n)         /* v[]: array to sort */
{                                       /* n: # elements in array */
    int gap, i, j, temp;

    for (gap = n / 2; gap > 0; gap /= 2)
    {
        printf ("shell sort gap %d\n", gap);
        for (i = gap; i < n; i++)
        {
            printf ("shell sort level %d\n", i);
            for (j = i - gap; j >= 0 && v[j] > v[j + gap]; j -= gap)
            {
                temp = v[j];
                v[j] = v[j + gap];
                v[j + gap] = temp;
            }
        }
    }
}

上面的程式是欣赏用的,我们的目的并不在讲 shell sort,而是要和各位谈谈如何
写出「乾净」的程式码。首先请看到上面程式里的大括号都是上下对齐的,大括号
内的东西向内缩四格,为什麽要这样做呢?看看以下错误的示□你就知道了:

        for (i = 0; i < 10; i++) {
                /* .... */
        }

第一个不好的习惯是上下的大括号不对齐,像 vi 或 jove 这种编辑器会自动替你
match 括号,提醒你是否有括号不对称的情形,这当然是很好用的工具。但是如果
我们现在用的是像 PE2  这种不会替你对括号的编辑器,而你自己又不把括号对齐
的话,那麽可以预见的是你常常会得到这个错误讯息:

        parse error at end of input

第二个不好的习惯是程式码不缩排,例如:

    for(gap=n/2;gap>0;gap/=2)
    {
    printf("shell sort gap %d\n",gap);
    for(i=gap;i<n;i++)
    {
    printf("shell sort level %d\n",i);
    for(j=i-gap;j>=0 && v[j]>v[j+gap];j-=gap)
    {
    temp=v[j];
    v[j]=v[j+gap];
    v[j+gap]=temp;
    }
    }
    }

所有的码挤成一堆,一点层次感也没有,层次感除了美观之外,它其实有重要的功
用,在像上面的多重回圈里我们要很用力的看才能看出它在干什麽,而不能如前面
的 shellsort.c 那麽一目了然。m程式码易读的最大好处是缩短除错的时间,减少
维护程式的成本0m。

至於运算元 (operator) 前後的空白,例如 i = j + 4; 等等,笔者个人是模仿
Quick BASIC 的风格,如果是单元运算元 (unitary operator) 就不加空白,如:
i++; ,二元运算元 (binary operator) 则前後加空白,如:i = j;。左小括号 (
前面一定加空白,逗号 , 後面也一定加空白。在 C 语言圣经 K&R 的版本里他们分
的更细,函数的左小括号前头没有空白,非函数的左小括号前头有空白,例如:

        printf("Hello, world!\n");      /* 函数 */
        for (i = 1; i < 10; i++)

笔者因为很喜欢按大大的 space 键听它叩叩的声音,所以左括号前一律加空白 :)
初学者常常因为懒惰而吃掉不少空白,套句补习班常用的广告词:今日不做,明日
後悔。别因一时的懒惰种下明日的苦果,什麽苦果?等你程式写到上千行你就知道了。

--
本文原作者为徐振家,原作刊载於星星神教总坛 ☆清华电机☆ test 板。
你可以以电子文件的形式将本文自由流传於台湾学术网路,但必须包含此版权声明。
原作者依中华民国著作权法之规定,享有本文之著作权,请勿抄袭以免触法。
未经授权任何人不得以任何形式对本文做任何修改及商业上之应用。
其他网路的转载或其他用途的应用,请先知会作者,并取得其同意。
对本文有任何疑问或意见请 mail 给 ax.bbs@bbs.ee.nthu.edu.tw,谢谢。


--
m;32m※ 转寄:.华南网木棉站 bbs.gznet.edu.cn.[FROM: mtlab.hit.edu.cn]
--

                              Enjoy Linux!
                          -----It's FREE!-----

※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: mtlab.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.376毫秒