【问题标题】:Scope of #define preprocessor in CC中#define预处理器的范围
【发布时间】:2011-06-16 22:49:49
【问题描述】:

#define 的范围是直到文件末尾。但它从哪里开始。 基本上我尝试了以下代码。

 #include<stdio.h>
 #include<stdlib.h>
 #define pi 3.14
 void fun();
 int main()
{
 printf("%f \n",pi);
 #define pi 3.141516
    fun();
return 0;
}
void fun(){
printf("%f \n",pi);}

上面程序的输出结果是

3.140000
3.141416

考虑到 main 的预处理,pi 的值应该是 3.141516 和主要的3.14之外。这是不正确的,但请解释原因。

【问题讨论】:

  • 记住它是预处理。它不知道也不关心代码的结构,在 #define 的情况下,它会按照相对于 #defined 变量的最新值的顺序进行替换。
  • 这段代码实际上是格式错误的:你不能#define 一个与当前定义的另一个宏同名的宏,除非它们的定义相同。所以,第二个#define pi 使程序格式错误。你需要先#undef pi
  • #define 的范围是直到文件的结尾。 不,文件的结尾或#undef 相同的宏标识符。
  • 顺便说一句:你的 pi 值是错误的。

标签: c c-preprocessor


【解决方案1】:

C 预处理器从上到下遍历文件并将#define 语句视为美化的复制和粘贴操作。一旦遇到#define pi 3.14 行,它就会开始用3.14 替换单词pi 的每个实例。预处理器不处理(甚至注意到)C 语言范围机制,如括号和花括号。一旦它看到#define,该定义就一直有效,直到到达文件末尾,使用#undef 未定义宏,或者(在这种情况下)使用另一个@ 重新定义宏987654328@声明。

如果您想要遵守 C 范围规则的常量,我建议在 const float pi = 3.14; 行中使用更多内容。

【讨论】:

  • "或者(在这种情况下)宏是用另一个 #define 语句重新定义的。"事实上,第二个 #define 没有前面的 #undef 会使程序格式错误。
  • 请注意,const 不会创建一个可用的常量,例如,在开关标签中:它会创建一个只读对象。 ideone.com/f3aON 的示例
【解决方案2】:

#define 的范围是从出现到文件末尾(或相应的 #undef),而不管任何中间的 C 范围。

【讨论】:

  • "#define 的范围是从出现到文件末尾" - 或者如果它在到达 EOF 之前是 #undef'ed。
【解决方案3】:

当您有预处理器问题时:

gcc -E foo.c > foo.i; vim foo.i

【讨论】:

    【解决方案4】:

    预处理器没有“范围”的概念——它操纵程序的文本,不知道文本是什么

    Symbol 从定义到编译单元结束(源文件和它包含的文件)定义

    【讨论】:

      【解决方案5】:

      预处理器处理完您的文件后大致如下所示:

       void fun();
       int main()
       {
          printf("%f \n",3.14);
         
          fun();
          return 0;
       }
       void fun(){
       printf("%f \n",3.141516);}
      

      这些是进入编译器进行编译的行(为了清楚起见,我丢弃了许多代码,只保留了您编写的代码)。由于预处理器将 #define 指令替换为您提供的文本/值,因此您在预处理后不再看到 #define 指令。所以很清楚将在控制台/终端上打印什么。

      【讨论】:

        【解决方案6】:

        据我所知,预处理器按照遇到它们的顺序使用#define 语句。在这种情况下,您的第一个 printf 语句正确打印 3.14 和第二个 3.141516(您的程序输出中是否有错字?)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-06-25
          • 1970-01-01
          • 1970-01-01
          • 2011-02-19
          • 2012-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多