符号常量


前面章节中代码里硬写入像 300、20 这类魔法数(magic numbers)是糟糕的编程习惯:

后续阅读代码的人很难看懂这些数字的含义;

而且当需要统一修改数值时,维护十分麻烦。


处理魔法数的方案之一,就是给数字赋予有意义的名字。利用 #define 指令可以定义符号名 / 符号常量,语法格式:

#define name 替换文本Code language: C++ (cpp)

定义之后,源代码中所有独立出现的 name(字符串引号内、或是作为其他标识符一部分的除外),都会被替换文本原样替换。


符号名命名规则和变量一致:由字母、数字组成,且首字符必须是字母

替换文本可以是任意字符序列,不局限于数字。

#include <stdio.h>
#define LOWER  0     // 表格下限 
#define UPPER  300   // 表格上限
#define STEP   20    // 步长

/* 打印华氏-摄氏温度对照表 */
int main()
{
    int fahr;
    for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
        printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}Code language: C++ (cpp)

执行结果和前面章节一样。

LOWERUPPERSTEP 都是符号常量,不是变量,因此不需要变量声明。
惯例:符号常量名称全部大写,方便和小写命名的普通变量区分。(非硬性要求)
注意:#define 这一行末尾不要加分号!

汇总

  1. 预处理机制
    #define 属于预处理指令,编译正式代码之前,预处理器只会做简单文本替换,不存在类型检查。
    例如 fahr = LOWER 在预处理后直接变成 fahr = 0
  2. 为什么不能带分号?
#define UPPER 300;Code language: C++ (cpp)

替换后代码:

for(fahr = 0; fahr <= 300<strong>;</strong>; fahr +=20)Code language: C++ (cpp)

多出分号,直接造成语法错误。

  1. 符号常量 vs 普通变量
  • #define:预处理文本替换,无内存分配,没有数据类型;
  • const int(C标准常量):属于变量,占有内存,具备类型,运行期生效。
  1. 命名规范约定
    常量全大写,下划线分隔:MAX_VALUEBUFFER_SIZE
    普通变量小写/驼峰:fahrtempValue

例子

下面是另外一个倒过来的例子,结果也是一样。

#include <stdio.h>
#define LOWER 0
#define UPPER 300
#define STEP  20

int main(void)
{
    int fahr;
    for (fahr = UPPER; fahr >= LOWER; fahr -= STEP)
        printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr - 32));
    return 0;
}Code language: C++ (cpp)

常量符号,就相当于编译器在正式编译之前做一次预处理,把所有的用到这个常量符号的地方都替换一遍,本质上最终编译的时候,和前面不适用常量符号的效果是一样的。

Previous:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注