当前位置:  编程技术>c/c++/嵌入式

C语言编程技巧 关于const和#define的区别心得

    来源: 互联网  发布时间:2014-10-11

    本文导语:  #define ASPECT_RATIO 1.653编译器会永远也看不到ASPECT_RATIO这个符号名,因为在源码进入编译器之前,它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号列表中。如果涉及到这个常量的代码在编译时报错,就会很令人费解,因为...

#define ASPECT_RATIO 1.653

编译器会永远也看不到ASPECT_RATIO这个符号名,因为在源码进入编译器之前,它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号列表中。如果涉及到这个常量的代码在编译时报错,就会很令人费解,因为报错信息指的是1.653,而不是ASPECT_RATIO。如果ASPECT_RATIO不是在你自己写的头文件中定义的,你就会奇怪1.653是从哪里来的,甚至会花时间跟踪下去。这个问题也会出现在符号调试器中,因为同样地,你所写的符号名不会出现在符号列表中。
解决这个问题的方案很简单:不用预处理宏,定义一个常量: 

const double ASPECT_RATIO = 1.653;


这种方法很有效。但有两个特殊情况要注意。

首先,定义指针常量时会有点不同。因为常量定义一般是放在头文件中(许多源文件会包含它),除了指针所指的类型要定义成const外,重要的是指针也经常要定义成const。例如,要在头文件中定义一个基于char*的字符串常量,你要写两次const:


const char * const authorName = "Scott Meyers";

关于const的含义和用法,特别是和指针相关联的问题,参见条款21。 

另外,定义某个类(class)的常量一般也很方便,只有一点点不同。要把常量限制在类中,首先要使它成为类的成员;为了保证常量最多只有一份拷贝,还要把它定义为静态成员:      

class GamePlayer {
private:
static const int NUM_TURNS = 5; // constant eclaration 
int scores[NUM_TURNS]; // use of constant
...
};


还有一点,正如你看到的,上面的语句是NUM_TURNS的声明,而不是定义,所以你还必须在类的实现代码文件中定义类的静态成员:


const int GamePlayer::NUM_TURNS; // mandatory definition;
// goes in class impl.file


你不必过于担心这种小事。如果你忘了定义,链接器会提醒你。


旧一点的编译器会不接受这种语法,因为它认为类的静态成员在声明时定义初始值是非法的;而且,类内只允许初始化整数类型(如:int, bool, char 等),还只能是常量。
在上面的语法不能使用的情况下,可以在定义时赋初值:
class EngineeringConstants { // this goes in the class
private: // header file
static const double FUDGE_FACTOR;
...
};
// this goes in the class implementation file
const double EngineeringConstants::FUDGE_FACTOR = 1.35;


大多数情况下你只要做这么多。唯一例外的是当你的类在编译时需要用到这个类的常量的情况,例如上面GamePlayer::scores数组的声明(编译过程中编译器一定要知道数组的大小)。所以,为了弥补那些(不正确地)禁止类内进行整型类常量初始化的编译器的不足,可以采用称之为“借用enum”的方法来解决。这种技术很好地利用了当需要int类型时可以使用枚举类型的原则,所以GamePlayer也可以象这样来定义:
class GamePlayer {
private:
enum { NUM_TURNS = 5 } // "the enum hack" — makes
// NUM_TURNS a symbolic name 
// for 5
int scores[NUM_TURNS];// fine
};


除非你正在用老的编译器(即写于1995年之前),你不必借用enum。当然,知道有这种方法还是值得的,因为这种可以追溯到很久以前的时代的代码可是不常见的哟。


回到预处理的话题上来。另一个普遍的#define指令的用法是用它来实现那些看起来象函数而又不会导致函数调用的宏。典型的例子是计算两个对象的最大值:
#define max(a,b) ((a) > (b) ? (a) : (b))


这个语句有很多缺陷,光想想都让人头疼,甚至比在高峰时间到高速公路去开车还让人痛苦。
无论什么时候你写了象这样的宏,你必须记住在写宏体时对每个参数都要加上括号;否则,别人调用你的宏时如果用了表达式就会造成很大的麻烦。但是即使你象这样做了,还会有象下面这样奇怪的事发生:


int a = 5, b = 0;
max(++a, b);// a 的值增加了2次
max(++a, b+10); // a 的值只增加了1次


这种情况下,max内部发生些什么取决于它比较的是什么值!
幸运的是你不必再忍受这样愚笨的语句了。你可以用普通函数实现宏的效率,再加上可预计的行为和类型安全,这就是内联函数(见条款33):
inline int max(int a, int b) { return a > b ? a : b; }
不过这和上面的宏不大一样,因为这个版本的max只能处理int类型。但模板可以很轻巧地解决这个问题:
template
inline const T& max(const T& a, const T& b)
{ return a > b ? a : b; }


这个模板产生了一整套函数,每个函数拿两个可以转换成同种类型的对象进行比较然后返回较大的(常量)对象的引用。因为不知道T的类型,返回时传递引用可以提高效率(见条款22)。


顺便说一句,在你打算用模板写象max这样有用的通用函数时,先检查一下标准库(见条款49),看看他们是不是已经存在。比如说上面说的max,你会惊喜地发现你可以后人乘凉:max是C++标准库的一部分。
有了const和inline,你对预处理的需要减少了,但也不能完全没有它。抛弃#include的日子还很远,#ifdef/#ifndef在控制编译的过程中还扮演重要角色。预处理还不能退休,但你一定要计划给它经常放长假


    
 
 

您可能感兴趣的文章:

  • 2013年7月和2013年8月编程语言排行榜
  • kliyx是使用C++语言编程的,还是用C语言编程的?
  • 2017 年热门编程语言排行榜出炉,你的语言上榜没?
  • 动态编程语言 LIME编程语言
  • 苹果OS X和IOS下最新编程语言swift介绍
  • 有了c语言基础,如何入手学习用c语言linux网络编程
  • PHP编程语言介绍及安装测试方法
  • LINUX下 C语言编程中 DIR 是做什么用的~?
  • 编程语言可扩展框架 LayerD
  • 新建 一 LINUX C语言编程交流群 大家若有兴趣就加入一起交流哈
  • unix/linux系统,支持那些语言编程??
  • 如何用C语言编程启动linux下的shell命令
  • 各位大侠,请推荐几本在UNIX环境下使用标准C语言编程的好书.谢谢啊!!!
  • 请问:linux 下 C语言编程 , 如何将 串口 由 全双工 变化为 半双工 通讯 方式?
  • 脚本编程语言 Crack
  • 基于JVM的编程语言 Golo
  • 一个小问题。Linux下编程语言的问题。
  • 在unix 中怎么实现 c 语言编程
  • 初学Linux要看什么书?, 请问Linux下C语言编程怎么设置环境?
  • 请问在linux中,怎样用c语言编程来实现对计算机的日期和时间的修改啊?
  • 在Linux的Eclipse中用C语言编程,求助
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 为什么要学linux环境下c语言编程
  • 请各位推荐几本UNIX下C语言编程学习的书!!(电子书籍也可)最好能详细介绍文件操作的!!!万分感谢!!!
  • 请教高手:在linux下c语言编程如何清空目标文件的内容?
  • Linux下的C语言编程
  • linux下的c语言编程问题
  • 请问:linux和windows下C语言编程有什么不同?(100分相送)
  • 请问哪里有<<精通Unix下C语言编程与项目实践>>电子书和原代码下载
  • Linux下C语言编程可以调用C++类库吗?
  • linux下C语言编程问题(curses库)
  • 在linux下用c语言编程遇到的一个问题,请高人指教:)
  • 关于linux下,C语言编程!!简单问题!
  • 问一个新手问题:在linux下的c语言编程跟windows下有什么不同?
  • 关于linux下c语言编程的问题
  • 菜鸟提问:关于linux(unix)c语言编程问题?
  • 【新手请教】关于linux下c语言编程
  • c语言编程问题:如果防止linux下程序的重复运行?
  • 调查:大家都用哪个Java语言编程?
  • 在SCO OpenSever中用C语言编程的问题!!!
  • UNIX下的编程语言有那些?
  • 并发编程语言 JR


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3