为什么我们使用预处理器指令来定义变量?

时间:2014-12-30 10:00:47

标签: c++ variables global-variables c-preprocessor preprocessor-directive

我有一段这样的代码:

/* 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;
}

4 个答案:

答案 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)

我会尝试列举专业人士,其他答案已经涵盖了缺点。

  1. 这是创建常量

    的简明方法
     #define PI 3.14
    
    每次遇到PI时,

    3.14将由预处理器替换,创建常量值的命名表示

  2. 替代

     double const pi = 3.14; 
    

    可以被黑客攻击

     const_cast<double>(pi) = 2.72; 
    

    这会导致未定义的行为。宏提供的文本替换不受const_cast

  3. 的影响
  4. 从C ++ 11开始,您可以更好地在文字中嵌入类型信息,从而减轻(稍微)类型安全性因素。请参阅here更多内容,但有一个简短的例子,请考虑例如,您可以随时声明类型安全的十秒倒计时常量

    #define CountDown 10s
    
  5. 最后但并非最不重要的......现实是海滩(我希望通过审查)。处理遗留代码时,您可能会遇到类似

    的内容
    #define C1  112
    #define C2  113
    ....
    #define C332 443
    

    这引出了一个问题:在修改上述列表时,您是否选择了一致性或编程风格?当然,常数可能会更多,并且散布在各地,而且在那里总是可以做出选择......

相关问题