我在一开始就看过很多使用#define
的程序。为什么我不应该声明一个常量全局变量?
答案 0 :(得分:9)
(这是一个C ++答案。在C语言中,使用宏有一个主要优点,那就是它们几乎是获得真正常量表达式的唯一方法。) < / p>
使用
#define
声明常量有什么好处?
没有。
我在开头看过很多使用
#define
的程序。
是的,那里有很多不好的代码。其中一些是遗产,其中一些是由于无能。
为什么我不应该声明一个常量全局变量?
你应该。
const
对象不仅是不可变的,而且具有类型,并且更容易调试,跟踪和诊断,因为它实际上存在于编译时(并且,至关重要的是,< em>在调试版本中有一个名称)。
此外,如果您遵守单一定义规则,那么当您更改宏的定义并忘记按字面意思重新编译整个项目时,您不必担心会造成一个全能的palaver代码是该项目的依赖。
而且,是的,具有讽刺意味的是const
对象仍被称为&#34;变量&#34 ;;当然,在实践中,它们并没有丝毫变化。
答案 1 :(得分:4)
使用#define声明常量有什么好处?
使用#define
声明一个常量是使用文字和幻数的一个更好的替代方法(也就是说,使用定义为#define NumDaysInWeek (7)
的值比仅使用7
更好的代码更好) ,但不是定义适当常数的优越替代方案。
你应该声明一个常量而不是#define
- 由于以下原因:
#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的数据中不存在该值) 。这是一个相对罕见的案例,但有效。
答案 2 :(得分:1)
根据C ++,Stroustroup的“ father ”,defining constants using macros should be avoided。
使用宏作为常量时最大的问题包括