【问题标题】:Issues by the redefinition of a macro in C在 C 中重新定义宏的问题
【发布时间】:2015-05-29 04:38:22
【问题描述】:

我想在程序运行期间更改宏的值,为此我编写了这个示例:

#include <stdio.h>
#define MAX  (65535 *0.5)

int main ( ){
float amp = 0.0;
float temp = 0.0 ;
temp    = MAX ;
char c;

while (1){
  printf(" MAX value %.2d.%.3d \n ", (short)temp,(short)(temp*1000));
  scanf("%c",&c);
  if( c =='x') {
    #undef MAX
    #define MAX  (65535 +amp);
    amp+= 0.1;
    temp = MAX;
  }
}
return 0 ; }

我有两个问题: 1. printf 没有显示所希望的值,例如 19.211,它总是 -32768.-32768 2. 我没有看到宏的值有任何变化。

知道我在这里做错了什么吗?

【问题讨论】:

  • 您是否期望输入'x'时宏的值会发生变化?
  • 确实是的,我已经阅读了这篇文章 stackoverflow.com/questions/9274500/… 并希望它会做到这一点
  • 宏不是变量。它们是宏。如果需要变量,请改用变量。

标签: c


【解决方案1】:

您只能在编译时定义宏。 c preprocessor 会在实际编译发生之前替换宏的每次出现,使用 gcc 您可以使用-E 开关查看预处理后生成的代码,如果您尝试使用不同的宏进行试验,您可能会更好地了解预处理器,请阅读链接以了解更多信息。

这个

if( c =='x') {
  #undef MAX
  #define MAX  (65535 +amp);
  amp+= 0.1;
  temp = MAX;
}

没有按照你的想法做。

如果对源代码执行预处理器,那么实际上会发生的是上面的sn-p会被编译成

if( c =='x') {
  amp+= 0.1;
  temp = MAX;
}

如您所见,它并没有按照您的想法行事。

另外,这和宏重定义问题无关,但是你的代码有一个bug,可以让它进入无限循环,这个

scanf("%c",&c);

在按下 Enter/Return 后将继续扫描留在stdin 中的'\n',因此您需要通过在这样的说明符之前添加一个空格来明确忽略该字符

scanf(" %c", &c);
/*     ^ white space goes here */

注意:另一个答案表明您使用了不正确的数据类型并提出了解决方案,您应该take a look at it,因为实际上您的程序似乎存在整数溢出问题。

【讨论】:

    【解决方案2】:

    让我们通过 C 预处理器 (CPP) 手动运行您的文件。结果是

    int main ( ) {
        float amp = 0.0;
        float temp = 0.0 ;
        temp = (65535 *0.5) ;
        char c;
    
        while (1) {
            printf(" MAX value %.2d.%.3d \n ", (short)temp,(short)(temp*1000));
            scanf("%c",&c);
            if( c =='x') {
    
    
                amp+= 0.1;
                temp = (65535 +amp);;
            }
        }
        return 0 ;
    }
    

    在编译器甚至看到您的源代码之前就对宏进行评估。您不能根据运行时做出的决定来更改宏的值。

    为什么不改用变量float max = ... 并根据用户输入更改其值?

    【讨论】:

      【解决方案3】:

      宏在编译期间被解析,因此在程序执行期间没有像MAX这样的东西 - 每个出现都已经被它的值替换(65535)。

      但是,如果你需要定义局部常量(就翻译单元而言是局部的),为什么不使用静态变量呢?

      static unsigned int MAX = 65535;
      

      然后:

      if (c == 'x')
      {
          MAX = 65535 + amp;
         //...
      }
      

      【讨论】:

        【解决方案4】:

        您使用了太短的数据类型并错误地打印了小数部分。考虑这样做:

        double i;
        printf(" MAX value %.2d.%.3d \n ", (int)temp,(int)(modf(temp,&i)*1000));
        

        ...而不是这个:

        printf(" MAX value %.2d.%.3d \n ", (short)temp,(short)(temp*1000));
        

        如果使用modf,请务必#include &lt;math.h&gt;

        不过,我对 MAX 宏的重新定义看起来很奇怪。宏是在编译时定义的,而不是在运行时定义的,所以大多数时候你不想重新定义宏。

        还要注意

        scanf("%c",&c);
        

        会将换行符作为一个单独的字符读取,因此您想改为:

        scanf(" %c",&c);
        

        ...消耗空格。请考虑检查EOF(文件结束)条件;目前你不这样做。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多