BBS水木清华站∶精华区

发信人: ax.bbs@bbs.ee.nthu.edu.tw. (athena), 信区: test 
标  题: 星星流讲座 0039 
发信站: ☆清华电机☆ (Thu Jul 13 19:31:40 1995) 
 
 
第 6 讲 之 0            常数与定字 
                        Topic: Constants and Literal 
 
什麽叫做常数 (constant) 呢?相对於变数是可变动的资料而言,常数就是 
不会变动的资料。例如圆周率π就是常见的数学常数。 
 
定义常数的方法有两种: 
 
第一种方法是使用 #define 叙述,例如: 
 
        #define Pi      3.1415926 
        #define BELL    '\007' 
        #define str     "Hello, world\n" 
 
我们前面提到过,以 # 开头的命令叫做编译指示 (compiler directives), 
所以 #define 也是一种编译指示。由我们上面的例子中可以看到常数不限任 
何资料型态都可以是常数,你可以定义常数的数值、字元或字串。 
 
第二种方法是使用 const 修饰子,例如: 
 
        const double Pi = 3.1415926; 
        const char BELL = '\007'; 
        const char str[] = "Hello, world\n"; 
 
我们可以看到 str 这个字元阵列的元素数目并未给定,这是因为若是 compiler 
在编译时就可以算出这个阵列的大小,那我们就可以省略阵列的元素个数。 
以 const 宣告的数,通常是在宣告时同时给定初值,之後所有对这个数的更 
动均视为错误。 
 
应用常数最常见的问题有三个:第一个是到底要用 #define 或是 const? 
第二个是 const string (literal) 的设定,第三个是若是函数参数为常数 
型态的指标又如何? 
 
我们先来解决第一个问题:到底要用 #define 或是 const? 
 
答案是用 const。为什麽?理由是因为使用 const 的话,compiler 才能 
防止错误地使用常数。我们说过 #define 是一种编译指示,而编译指示是 
以下图的方式被处理的: 
 
                        原始码 (source code) 
                          ↓ 
           + - - - - - - - - - - - - - - + 
           | 前置处理程式 (preprocessor) | 
           |              ↓ 扩张後的码  | 
           | 编译程式 (compiler)         | 
           |              ↓             | 
           | 最佳化程式 (optimizer)      | 
           + - - - - - - - - - - - - - - + 
                          ↓ 
                        中间码 (intermediate code) 
 
原始码由前置处理程式处理之後,变成扩张後的码 (expanded source), 
然後才丢给 compiler 去编译。前置处理程式是 cpp (C PreProcessor), 
它也是由 gcc 偷偷地去呼叫的。前置处理程式会把所有的 #define 所产生 
的常数直接代换进数值,也就是说像 
 
        printf ("%f\n", Pi); 
 
这一行叙述,经过 cpp 处理之後就会变成 
 
        printf ("%f\n", 3.1415926); 
 
这有什麽缺点呢?第一,cpp 并不会替你检查型态是否正确。第二,compiler 
根本看不到 Pi 这个符号 (因为被代换掉了),所以 compiler 产生出来的除 
错资料也没有 Pi 这个符号,因此你若使用除错器来替你的程式侦错,也看不 
到 Pi 这个符号,那意味著除错变的非常地麻烦。所以尽量使用 const 来代 
替 #define。 
 
第二个和第三个问题,留待下讲再叙。 
 
-- 
本文原作者为徐振家,原作刊载於星星神教总坛 ☆清华电机☆ test 板。 
你可以以电子文件的形式将本文自由流传於台湾学术网路,但必须包含此版权声明。 
原作者依中华民国著作权法之规定,享有本文之著作权,请勿抄袭以免触法。 
未经授权任何人不得以任何形式对本文做任何修改及商业上之应用。 
其他网路的转载或其他用途的应用,请先知会作者,并取得其同意。 
对本文有任何疑问或意见请 mail 给 ax.bbs@bbs.ee.nthu.edu.tw,谢谢。 
 
 

BBS水木清华站∶精华区