我有一段这样的代码:
/* T matrix */
#define T11 0
#define T12_re 1
#define T12_im 2
int main(int argc, char *argv[])
{
return 1;
}
我的问题是为什么它使用预处理程序指令来定义全局变量,而不是简单地使用这样的代码:
/* T matrix */
double T11 = 0;
double T12_re = 1;
double T12_im = 2;
int main(int argc, char *argv[])
{
return 1;
}
答案 0 :(得分:1)
预处理程序符号是不是变量。在您的第一个代码中,T13_im
(etc ...)不是变量(但是在解析时扩展为4
的预处理名称)
在你的第二个代码中(它没有像你编写的那样编译),你可能有
const double T12_re= 1.0;
然后您声明了T12_re
类型的变量const double
。
阅读C preprocessor上的wikipage,GNU cpp的文档,并意识到编译器只看到预处理的形式;对于您的文件yoursource.cc
,您可以使用命令
yoursource.ii
获取预处理表单g++ -Wall -C -E yoursource.cc > yoursource.ii
,然后使用寻呼机或编辑器浏览生成的yoursource.ii
有时,预处理器允许使用像this这样的可爱技巧。而且你不能总是使用变量。例如,case
表达式应该是编译时常量,不能在C const int
变量中。 (您可以使用一些enum
,它在C和C ++中有所不同。)
答案 1 :(得分:1)
对您的问题的明确答案为什么是不可能的 - 没有理由使用像#define
这样的过时结构。主要原因是,在过去,这是定义常量的唯一方法(因为我们讨论的是常量而不是变量。所以主要原因是缺乏知识。
不要使用这样的结构 - 使用适当的C ++常量,比如
const double T12_re = 0.1;
答案 2 :(得分:0)
预处理器指令不用于定义变量,#define只是一种方便使用您将使用多次的代码的方法,或者将来您可以修改而无需更改任何代码行。 #define只是将一个值替换为其他值,例如:
#define PI 3.14159265
....
float diameter = (circ / PI);
使用#define和常量或变量之间的最大区别在于,使用#define不会为此值分配内存,在编译期间,编译器只需将PI替换为代码中的3.14159265。 define是以这种方式使用的,因为在编译期间是不可更改的(与常量相同)并且不分配内存。
在编译期间,C ++编译器会生成一个替换了定义的代码,因此编译过程中的上述代码将是这样的:
float diameter = (circ / 3.14159265);
如果你想分配内存,只需使用常量:
const float PI = 3.14159265;
obs(#define也用作宏)
答案 3 :(得分:0)
我会尝试列举专业人士,其他答案已经涵盖了缺点。
这是创建常量
的简明方法 #define PI 3.14
每次遇到PI
时, 3.14
将由预处理器替换,创建常量值的命名表示
替代
double const pi = 3.14;
可以被黑客攻击
const_cast<double>(pi) = 2.72;
这会导致未定义的行为。宏提供的文本替换不受const_cast
从C ++ 11开始,您可以更好地在文字中嵌入类型信息,从而减轻(稍微)类型安全性因素。请参阅here更多内容,但有一个简短的例子,请考虑例如,您可以随时声明类型安全的十秒倒计时常量
#define CountDown 10s
最后但并非最不重要的......现实是海滩(我希望通过审查)。处理遗留代码时,您可能会遇到类似
的内容#define C1 112
#define C2 113
....
#define C332 443
这引出了一个问题:在修改上述列表时,您是否选择了一致性或编程风格?当然,常数可能会更多,并且散布在各地,而且在那里总是可以做出选择......