使用#define声明常量的好处是什么?

What is the benefit of using #define to declare a constant?

本文关键字:是什么 #define 声明 常量 使用      更新时间:2023-10-16

我见过很多一开始就使用#define的程序。为什么不声明一个常量全局变量呢?

(这是一个c++答案。在C语言中,使用宏有一个主要的优点,那就是它们几乎是获得真正的常量表达式的唯一方法。)


使用#define声明常量的好处是什么?

没有。

我见过很多程序一开始就使用#define

是的,有很多不好的代码。有些是遗产,有些是由于无能。

为什么不声明一个常量全局变量呢?

你应该。

const对象不仅不可变,而且具有类型,并且更容易调试、跟踪和诊断,因为它实际上在编译时存在(并且,关键的是,在调试构建中有一个名称)。

此外,如果你遵守一个定义规则,当你改变宏的定义,忘记重新编译你的整个项目,以及任何依赖于这个项目的代码时,你不必担心会引起一个巨大的麻烦。

是的,具有讽刺意味的是,const对象仍然被称为"变量";当然,在实践中,它们一点也不是可变的。

使用#define声明常量的好处是什么?

使用#define声明常量是使用文字和幻数的更好选择(也就是说,代码使用定义为#define NumDaysInWeek (7)的值比简单使用7要好得多),但不是定义适当常量的更好选择。

应该声明一个常量,而不是#define -ing它,原因如下:

  • #define在源代码中执行标记/文本替换,而不是语义替换。

    这会破坏命名空间的使用(#defined变量被替换为值并且不包含完全限定名)。

    即给定:

    namespace x {
    #define abc 1
    }
    

    x::abc是一个错误,因为编译器实际上试图编译x::1(这是无效的)。

    另一方面,

    abc将始终被视为1,禁止您在任何其他本地上下文中或命名空间中重新定义/重用标识符abc。

  • #define以文本方式插入参数,而不是作为变量:

    #define max(a, b) a > b ? a : b;
    int a = 10, b = 5;
    int c = max(a++, b); // (a++ > b ? a++ : b); // c = 12
    
  • #define绝对没有语义信息:

    #define pi 3.14 // this is either double or float, depending on context
    /*static*/ const double pi = 3.14; // this is always double
    
  • #define使您(开发人员)看到与编译器不同的代码

    这可能不是什么大事,但是以这种方式产生的错误是模糊的,意想不到的,并且浪费了大量时间(您可能会看到一个错误,代码对您来说非常好,并且诅咒编译器半天,只是后来才发现表达式中的一个符号实际上意味着完全不同的东西)。

    如果您使用调试器来使用上面的pi声明之一进行编码,那么第一个声明将导致调试器告诉您pi是一个无效的符号。

编辑(本地静态const变量的有效示例):

const result& some_class::some_function(const int key) const
{
   if(map.count(key)) // map is a std::map<int,result> member of some_class
       return map.at(key); // return a (const result&) to existing element
   static const result empty_value{ /* ... */ }; // "static" is required here
   return empty_value;  // return a (const result&) to empty element
}

这显示了一种情况,当你有一个const值,但它的存储需要比函数更持久,因为你返回一个const引用(值不存在于some_class的数据中)。

根据c++, Stroustroup的"之父",应该避免使用宏定义常量。

使用宏作为常量的最大问题包括

  • 宏覆盖代码中出现的所有内容。例如变量定义。这可能导致编译错误或未定义行为。
  • 宏使代码很难阅读和理解,因为宏的复杂性可以隐藏在头文件中,程序员无法清楚地看到