首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

《小弟我的第一本C++书》节选:3.2.5 用宏与const关键字定义常量

2014-01-05 
《我的第一本C++书》节选:3.2.5用宏与const关键字定义常量http://chenlq.net常量就像C++世界的“雷锋”,只做好

《我的第一本C++书》节选:3.2.5 用宏与const关键字定义常量
http://chenlq.net
常量就像C++世界的“雷锋”,只做好事而不留名字。但是,我们不能太亏待“雷锋”,也要给常量一个名分。更重要的是,有时候给常量一个名分是必要的。例如,要编写一个有关圆的计算程序,无疑会多次用到?常量。那么,是不是一定要在程序中反复多次地写3.14159呢?不是,给常量?一个名分,就可以解决这个问题。 如果常量也有一个名分,就可以在程序中多次使用常量的名字来代表常量,也就达到了在程序中多次使用同一个常量的目的。给常量一个名分,通常有两种方法:使用宏或者const关键字。 所谓的宏,就是将某个无明确意义的值(例如,3.14159,知道的认为是圆周率,不知道的认为是某个奇怪的数字),定义为某个有明确意义的标识符(例如,PI,所有人都会认为是圆周率)。然后,就可以在代码中使用这个有意义的标识符,从而使代码更具可读性。在C++中,可以使用#define预编译指令来定义一个宏:
1

#define 宏名称 宏值

其中,“宏名称”就是要定义的宏,通常用一个大写的有意义的名称来表示。“宏值”就是这个宏所代表的常量,它可以是一个常数、一个字符串,甚至是一个更加复杂的语句。比如,可以将?值定义为一个宏PI:
1

#define PI 3.14159

有了常量所对应的宏,就可以在代码中使用宏来代替常量进行相应的计算。例如:
1
2
3
4

// 计算圆的周长
double fCircle = 2 * PI * fR;
// 计算圆的面积
double fArea = PI * fR * fR;

这里,使用了PI宏代替了原本应该使用的常量3.14159。宏的本质是一种替代。当预编译程序在处理源代码时,如果发现代码中使用了宏,就会用宏的值来代替宏。例如,上面的代码会被分别修改为
1
2
3

// 宏替换后的代码
double fCircle = 2 * 3.14159 * fR;
double fArea = 3.14159 * fR * fR;

归根结底,还是在代码中多次使用了常量,只是预编译程序帮我们完成了部分繁琐的工作而已。 使用宏给常量一个名分,除了可以避免多次输入重复使用的常量之外,宏还进行超值大赠送,带来了一些额外的好处。

    1. 宏让代码更简洁明了 一个宏名称往往比一个简单无意义的常量数字或者常量字符串包含了更加丰富的信息,可以增加代码的可读性;同时,宏比常量更简单,可以使代码更简洁。对比下面两段代码:

     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    // 不使用宏的代码
    for( int i = 0; i < 100; ++i )
        {
            // ...
        }
    // 使用宏的代码
    #define MIN 0
    #define MAX 100
        for( int i = MIN; i < MAX; ++i )
        {
            // ...
        }

    通过对比发现,虽然两段代码实现的功能是一样的,但是给代码阅读者的信息不太相同。第一段代码只是表示这个循环是从0到100之间,至于为什么是从0到100,只有自己去猜测了。第二段代码通过宏的使用,明确地告诉了我们这个循环是在一个最小值和最大值之间进行的,这样可以从代码本身获得更加丰富的信息。
    2. 宏让代码更加易于维护 如果需要修改某个在代码中被多次使用的常量,只需要修改宏的定义就可以了,而不用修改代码中所有的宏。例如,如果想提高圆周率的精度,只需要将宏定义修改为

     
    1
    
    #define PI 3.1415926

    然后所有使用PI宏的地方都会使用这个更高精度的?值进行计算。

虽然宏的使用可以带来便利,但是因为它是在预处理的时候进行无条件的替换,并没有明确指定这个常量的数据类型,所以带来便利的同时也容易带来问题。C++使用另一种更加稳妥的方法来代替宏的这一功能,这就是const关键字。 变量的值是可以修改的,可以在定义变量的时候加上const关键字,让变量的值不可修改,从而成为常量。const关键字的使用格式如下:
1

const 数据类型 常量名 = 常量值;

相比于变量的声明方式,我们只是在数据类型前加了const关键字,该关键字告诉编译器这条语句所定义的变量的值是不可修改的,也就是说,该变量可以当成常量来使用。需要注意的是,因为常量的值不可以修改,所以必须在定义常量的同时完成它的赋值。例如:
1
2

// 定义常量PI
const double PI = 3.14159;

使用const的常量一经定义后,就不能再进行修改,否则会产生编译错误。例如,如果想在程序中降低PI的精度,偷工减料是不行的,例如:
1
2

// 不能修改const常量的值
PI = 3.141;

这样给一个const修饰的变量赋值是不行的。正是编译器检查变量赋值,使得我们无法对const修饰的变量进行赋值,从而也就无法改变这个变量的值。既然变量的值无法改变,那么这个变量也就成了常量。 既然宏和const关键字都可以用来给常量一个名分,那么该如何选择呢?到底是用宏还是用const关键字?应该更多地使用const关键字。比如,要定义PI这个常量,可以采用以下两种方式:
1
2
3
4

// 宏方式
#define PI 3.14159
// const方式
const double PI = 3.14159;

这两种方式在语法上都是合法的,但是第二种方式要比第一种方式好,因为如果使用#define定义宏,PI会在代码的预编译阶段被预编译处理器替换成3.14159,宏的名称不会出现在符号表中,这样会给代码后期的调试带来麻烦,可能会遇到一个数字,却不知道它从何而来,这就是我们常说的Magic Number(像拥有魔力一样不知从何而来的数)。使用const定义,既可以保证PI值的唯一性,又便于调试,同时还可以对数据类型进行检查,借助编译器来减少错误的发生。所以,我们总是优先使用const关键字来定义常量。
[解决办法]
没有必要写这么多

热点排行