简体   繁体   English

通过在C中重新定义宏发出的问题

[英]Issues by the redefinition of a macro in C

I want to change the value of a macro during the run of the program, for that I've wrote this example : 我想在程序运行期间更改宏的值,为此,我编写了以下示例:

#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 ; }

I've got two problems : 1. the printf doessn't show the values as hoped, for instand 19.211, it always -32768.-32768 2. I don't see any change of the value of the macro. 我有两个问题:1. printf并没有显示希望的值,为了理解19.211,它始终为-32768.-32768 .我看不到宏的值有任何变化。

any idea what I'm doing wrong here ? 知道我在做什么错吗?

You can only define macros at compile time. 您只能在编译时定义宏。 The c preprocessor replaces every occurrance of a macro before actual compilation happens, with gcc you can see what code was generated after preprocessing by using the -E switch, if you try it experimenting with different macros, you may get to understand the preprocessor a little better, read the link to understand more. c预处理程序会在实际编译发生之前替换宏的所有出现,使用gcc,您可以使用-E开关查看预处理后生成的代码,如果尝试使用不同的宏进行试验,则可能会稍微了解一下预处理程序更好,请阅读链接以了解更多信息。

This 这个

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

does not do what you think. 不按照你的想法做。

If you execute the preprocessor on the source code, then what will actually happen is that the snippet above will be compiled as 如果您在源代码上执行预处理器,则实际发生的是上面的代码段将被编译为

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

so as you can see, it doesn't do what you think. 如您所见,它并没有按照您的想法进行。

Also, this is not related to the macro redefinition issue, but your code has a bug that can make it enter an infinite loop, this 此外,这与宏重新定义问题无关,但是您的代码中存在一个错误,该错误可能会使它进入无限循环,这

scanf("%c",&c);

will keep scanning the '\\n' that is left in the stdin after pressing Enter/Return , so you need to explicitly ignore that character by adding a white space before the specifier like this 按下Enter / Return后 ,将继续扫描stdin 输入中'\\n' ,因此您需要通过在这样的说明符之前添加空格来显式忽略该字符

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

Note : another answer has suggested that you are using the incorrect data type and suggested a solution, you should take a look at it , since in fact it seems your program has an integer overflow issue. 注意 :另一个答案表明您使用的数据类型不正确,并提出了一种解决方案,您应该对它进行查看 ,因为实际上您的程序似乎存在整数溢出问题。

Macros are resolved during compilation, so during program execution there is no such thing like MAX - each occurence was already replaced by its value ( 65535 ). 宏是在编译期间解析的,因此在程序执行期间不会出现MAX类的东西-每次出现都已被其值替换( 65535 )。

However, if you need to define local constant (local in terms of translation unit), why not use static variable? 但是,如果需要定义局部常量(以转换单位表示局部变量),为什么不使用静态变量?

static unsigned int MAX = 65535;

And then: 接着:

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

Let's run your file through the C preprocessor (CPP) manually. 让我们通过C预处理程序(CPP)手动运行文件。 The result is 结果是

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

Macros are evaluated before the compiler even sees your source code. 在编译器甚至没有看到您的源代码之前就对宏进行评估。 You cannot change the value of a macro based on a decision taken at runtime. 您不能基于运行时做出的决定来更改宏的值。

Why not instead use a variable float max = ... and change that one's value depending on user input? 为什么不使用变量float max = ...并根据用户输入更改其值呢?

You are using too short data type and printing the fractional part incorrectly. 您使用的数据类型太短,并且小数部分打印不正确。 Consider doing this: 考虑这样做:

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

...instead of this: ...代替此:

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

Be sure to #include <math.h> if using modf . 如果使用modf请确保#include <math.h>

Your redefinition of the MAX macro looks strange to me, though. 但是,您对MAX宏的重新定义对我来说似乎很奇怪。 Macros are defined at compile time, not at run time, so most of the time you don't want to redefine macros. 宏是在编译时定义的,而不是在运行时定义的,因此大多数时候您都不想重新定义宏。

Note also that 另请注意

scanf("%c",&c);

will read the newline as a separate character, so you want to do instead: 会将换行符作为一个单独的字符读取,因此您需要这样做:

scanf(" %c",&c);

...to consume whitespace. ...消耗空白。 Do consider checking also for the EOF (end-of-file) condition; 请考虑同时检查EOF (文件结束)条件; currently you don't do that. 目前您不这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM