[编程好习惯] 避免使用魔数
来源:李云 责任编辑:栏目编辑 发表时间:2013-07-01 11:47 点击:次
魔数(magic number),即在编写程序时直接在程序中运用数字,而不是采用定义宏或是const变量的方式,图1是使用了魔数的一个示例程序。其中的64是指Msk的最大字节数。从这一程序中可以看出,Msk的最小字节数是MIN_MSK_LEN,即20。采用魔数的危害有:
1) 降低了程序的可读性。有人可能会提出,那加一些注释不就完了吗?如果真是采用加注释的方式,那为什么不将其定义成一个宏或是const常量呢?要知道查看注释的效率肯定没有直接看代码来得快和方便,也不存在不同步的问题(代码与注释有可能不同步)。
2) 如果下一次这个最大值要从64改为128,那得在adjustMask()中对每一处都进行更改。另外,当一个项目较大时,魔数的存在会使得程序维护非常、非常困难。
由此看来,这里的“魔”不应理解成象“魔法(magic)”那样神奇,而应理解为象“魔鬼(monster)”那样可怕。
1) 降低了程序的可读性。有人可能会提出,那加一些注释不就完了吗?如果真是采用加注释的方式,那为什么不将其定义成一个宏或是const常量呢?要知道查看注释的效率肯定没有直接看代码来得快和方便,也不存在不同步的问题(代码与注释有可能不同步)。
2) 如果下一次这个最大值要从64改为128,那得在adjustMask()中对每一处都进行更改。另外,当一个项目较大时,魔数的存在会使得程序维护非常、非常困难。
由此看来,这里的“魔”不应理解成象“魔法(magic)”那样神奇,而应理解为象“魔鬼(monster)”那样可怕。
example.c
00290: #define MIN_MSK_LEN 20
00291:
00292: int adjustMsk (MskContext* Context)
00293: {
00294: char temp [64] = {0};
00295:
00296: if (Context->lenMsk > 64) {
00297: memcpy (temp, Context->msk + (Context->lenMsk - 64), 64);
00298: ...
00399: memcpy (Context->msk, temp, 64);
00300: }
00301: else if (Context->lenMsk < MIN_MSK_LEN) {
00302: return ERROR;
00303: }
00304: ...
00305: }
00290: #define MIN_MSK_LEN 20
00291:
00292: int adjustMsk (MskContext* Context)
00293: {
00294: char temp [64] = {0};
00295:
00296: if (Context->lenMsk > 64) {
00297: memcpy (temp, Context->msk + (Context->lenMsk - 64), 64);
00298: ...
00399: memcpy (Context->msk, temp, 64);
00300: }
00301: else if (Context->lenMsk < MIN_MSK_LEN) {
00302: return ERROR;
00303: }
00304: ...
00305: }
图1
图2是采用宏之后的版本。其中定义了MAX_MSK_LEN的大小为64,如果其它函数中也需要用到Msk的最大值,那么也可以引用这一宏。如果下一次想将最大值从64改为128时,只要改MAX_MSK_LEN宏的定义就行了。另外,这种宏定义的存在有利于模块与模块之间共享,从而在一定程度上提高重用性。example.c
00289: #define MIN_MSK_LEN 20
00290: #define MAX_MSK_LEN 64
00291:
00292: int adjustMsk (MskContext* Context)
00293: {
00294: char temp [MAX_MSK_LEN] = {0};
00295:
00296: if (Context->lenMsk > MAX_MSK_LEN) {
00297: memcpy (temp, Context->msk + (Context->lenMsk - MAX_MSK_LEN),
00298: MAX_MSK_LEN);
00399: ...
00300: memcpy (Context->msk, temp, MAX_MSK_LEN);
00301: }
00302: else if (Context->lenMsk < MIN_MSK_LEN) {
00303: return ERROR;
00304: }
00305: ...
00306: }
00289: #define MIN_MSK_LEN 20
00290: #define MAX_MSK_LEN 64
00291:
00292: int adjustMsk (MskContext* Context)
00293: {
00294: char temp [MAX_MSK_LEN] = {0};
00295:
00296: if (Context->lenMsk > MAX_MSK_LEN) {
00297: memcpy (temp, Context->msk + (Context->lenMsk - MAX_MSK_LEN),
00298: MAX_MSK_LEN);
00399: ...
00300: memcpy (Context->msk, temp, MAX_MSK_LEN);
00301: }
00302: else if (Context->lenMsk < MIN_MSK_LEN) {
00303: return ERROR;
00304: }
00305: ...
00306: }
相关新闻>>
- 发表评论
-
- 最新评论 更多>>