/--- date: 2014-08-04 01:15:41 +0800 categories: 扯淡 ---/

论处女座的IT修养

今天说两件事: 一个是场景还原。 一个是IT企业对IT领域的人才贡献。

场景还原

就场景还原来讲,举个输入文字的例子。一般我们打开电脑,默认会是英文键盘输入状态,如果这时想输入中文,一般的流程会是这样:

  1. 将输入法切换至中文输入状态(比如必应拼音输入法);
  2. 输入中文;
  3. 将输入法切回至英文键盘输入状态,然后再干别的事情。

其它情况类推。那么假如中途被迫中断而去做了别的事情,我们也应当将先将场景还原至初始的英文键盘输入状态。

我想这就是处女座更适合做编码工作的原因吧:P 其实生活中也有许多这样的例子,比如用完一个工具后,把它放回原地等等。下面我举两个编程方面的例子。

这里我将重点放在文件的打开、关闭上,其他细节及错误处理忽略不计,源码如下。

另:goto语句一般不推荐使用,因为它会破坏程序的逻辑结构。但在两种情况下,使用goto语句带来的好处会大于弊出:一种是在处理深层嵌套时;一种是在集中错误处理时。详见《The C Programming Language》第二版第3.8小结。以下源码是为了展现该功能而强制使用了goto

#include <stdio.h>
#include <stdlib.h>

static void
usage(void)
{
        printf("用法: cpy2 src des\n");
        printf("将源文件src拷贝到目的文件des中。\n\n");
        return ;
}

int
main(int argc, char *argv[])
{
        FILE *in = NULL;
        FILE *out = NULL;

        if (argc != 3) {
                usage();
                goto END;
        }

        // 开始复制之前的场景设定工作
        // 注意这里假如出现打开文件错误时的处理方式
        in = fopen(argv[1], "r");
        if (in == NULL)
                goto END;
        out = fopen(argv[2], "w");
        if (out == NULL)
                goto END1;

        // 开始复制
        int c;
        while ((c = getc(in)) != EOF)
                putc(c, out);

        // 复制完成之后的清理工作
        // 注意这里关闭文件的先后顺序和打开文件的先后顺序是相反的(这里假定关闭文件不会出现错误)
        // 注意这里标签 END2 实际上是没用的,这里写出了,只为其对照作用
END2:
        fclose(out);
        out = NULL;
END1:
        fclose(in);
        in = NULL;
END:
        exit(0);
}

errno是一个int类型变量。它的定义如下:

extern int errno;

对于errno变量的使用,有以下两条原则需要说明。详见《Advanced Programming in the UNIX Environment》第二版第1.7节。

  1. 不管错误发生与否,对于一个程序来讲,它的值永远不会表现的那么清晰,因为可能随时会被其他函数修改。所以,当一个错误发生时,如果需要,你必须立刻检查该变量的值。
  2. 它的值永远不会被其他函数设置为0,除非你自己在编码过程中指定。
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

static void
testfun(void)
{
        int fd;
        int errno_saved;

        errno_saved = errno;

        if ((fd = open("text_file.txt", O_WRONLY)) < 0)
                perror("openfile");  // 注意如果打开文件失败,这里errno将会被设置为一个新值,比如NNOENT。这里我使用perror函数将其新值所代表的含义给输出至屏幕

        // ...

        errno = errno_saved;
}

int
main(void)
{
        // ...

        testfun();

        // ...

        return 0;
}

其实,这样的例子还有很多,比如内存的分配与释放;比如对数据库进行的操作,有打开,就应有对应的关闭;比如中断的使用,在发生前保存此刻场景,发生后还原该场景,这里通常会采用到栈技术;再比如互斥锁,使用资源前上锁,使用完资源后将锁解除。

IT企业对IT领域的人才贡献

IT企业对IT领域的人才贡献,简单的说即是对IT新人的培养。企业不能一味的只是拿来主义吧,我想。

(完)