C++中的宏和const有什么区别?

Amm*_*kun 20 c++ macros const

我在技术访谈中被问到这个问题:

constC++中的a 和宏有什么区别?

我的回答是宏是一个预处理器指令,如果使用宏,可能很难调试应用程序,因为它在编译之前被常量表达式替换,而a const可以有类型标识符并且易于调试.

任何人都可以指出任何其他差异,哪些应该是首选?

编辑:

来自IBM C++文档:

以下是一些区别#defineconst类型修饰符:

  1. #define指令可用于为数字,字符或字符串常量创建名称,而可声明任何类型的const对象.

  2. const对象受变量的作用域规则约束,而使用的常量不受约束#define.与const对象不同,宏的值不会出现在编译器使用的中间源代码中,因为它们是内联扩展的.内联扩展使得调试器无法使用宏值.

  3. 宏可以用在常量表达式中,例如数组绑定,而const对象则不能.(我认为我们肯定需要使用宏来定义array_size.

  4. 编译器不会对宏进行类型检查,包括宏参数.

zwo*_*wol 25

宏和常量并不是一成不变的,每个都有时适合于环境,而你的答案只会在差异的表面划伤.此外,C++有两种不同的常量.

const限定符定义的常量最好被认为是一个不可修改的变量.它具有变量的所有属性:它有一个类型,它有一个大小,它有链接,你可以取其地址.(编译器可能会优化掉其中的一些属性,如果它可以逃脱它:例如,从未使用过地址的常量可能不会被发送到可执行映像中.但这只能通过as-if规则的优雅.你唯一不能对const基准做的就是改变它的价值.定义的常量enum略有不同.它有一个类型和一个大小,但它没有链接,你不能采取它的地址,它的类型是唯一的.这两个都在翻译阶段7中处理,因此它们不能是左值或左值.(对于上一句中的行话我很抱歉,但我不得不写几段.)

宏的约束要少得多:它可以扩展到任何令牌序列,只要整个程序仍然是一个格式良好的程序.它没有变量的任何属性.应用sizeof&宏可能会或可能不会做一些有用的事情,具体取决于宏扩展到什么.宏有时被定义为扩展为数字文字,这些宏有时被认为是常量,但它们不是:"编译器本身"(即转换阶段7)将它们视为数字文字.

如今,通常认为良好的做法是在常量不执行时使用宏.宏不遵循与所有其他标识符相同的范围规则,这可能会造成混淆,如果使用常量,则可以向转换阶段7提供更多信息,从而也为调试器提供更多信息.但是,宏允许你做任何其他方式无法完成的事情,如果你需要做其中一件事,你应该毫不犹豫地使用它们.(在这个意义上,正在拉动它们的重量的宏通常只是扩展到数字文字,尽管我不会说永远不会.)

编辑:这是宏做一些有趣事情的例子.绝不是形状或形成常数.可能有一种方法可以在没有宏的情况下获得相同的效果(如果你知道一个不涉及字符串流的话,我会好奇地听到它!)但我认为它很好地说明了它的功能和宏的危险(对于后者,考虑如果在一个非常具体的背景之外使用它将会做什么......)

static double elapsed()
{ ... }
#define ELAPSED '[' << std::fixed << std::setprecision(2) << elapsed() << "] "

// usage:
for (vector<string>::iterator f = files.begin(); f != files.end(); f++) {
    cout << ELAPSED << "reading file: " << *f << '\n';
    process_file(*f);
}
Run Code Online (Sandbox Code Playgroud)


Alo*_*ave 12

每个人都应该喜欢const int sum = 1;#define sum 1了几个原因:

基于范围的机制:

#defines不尊重范围,因此无法创建类范围的命名空间.虽然const变量可以在类中作用域.

在编译错误期间避免奇怪的魔法数字:

如果您正在使用#define它们在预编译时被预处理器替换那么如果您在编译期间收到错误,那将会引起混淆,因为错误消息不会引用宏名称而是值,它将显示为突然值,并且一个人会浪费很多时间在代码中跟踪它.

易于调试:

同样出于同样的原因,虽然调试#define没有提供任何帮助.
避免上述两种情况const都是更好的选择.