C程序使用用户自定义

时间:2016-07-02 06:25:44

标签: c

void fun()
{
// Essentially this is a function with an empty body
// And I don't care about () in a macro
// Because this is evil, regardless
#define printf(a, b) (printf)(a, b*2)
}

void main() // I know this is not a valid main() signature
{
  int x = 20;
  fun();
  x = 10;
  printf("%d", x);
}

我对#define行有疑问!你能不能给我一些链接文档来理解这行代码。答案是20。

3 个答案:

答案 0 :(得分:2)

#define 定义预编译器宏在编译器执行任何操作之前由预处理器处理。 预处理器甚至不知道代码行是在函数内部还是外部。

通常在包含头文件后定义宏。 即在#include语句之后。

答案 1 :(得分:1)

预处理器宏不是实际C语言的一部分,宏和其他预处理器指令的处理是在编译器 1 之前完成的单独步骤。这意味着宏不遵循C的规则,特别是在作用域方面,宏总是“全局的”。

这意味着您认为在printf函数中调用的main函数实际上不是printf函数,而是printf 宏< / EM>

在预处理(和删除评论)后,您显示的代码将如下所示:

void fun()
{
}

void main()
{
  int x = 20;
  fun();
  x = 10;
  (printf)("%d", x*2);
}

发生的事情是printf宏的调用被调用printf函数替换。由于宏的第二个参数乘以2,输出将为10 * 2,即20

这个程序说明了宏的一个主要问题:它很容易让程序看起来像普通的程序,但它做了一些意想不到的事情。定义实际评估为true的宏false很简单,相反,更改完全与truefalse进行比较的含义。你应该从这样的例子中学到的唯一一件事是宏是多么糟糕,你永远不应该尝试使用宏来“重新定义”语言或标准函数。当使用很少和良好的宏是好的,将使C编程更容易。错误地使用,就像在这个例子中一样,它们会使代码变得不可读和不可维护。

1 预处理器曾经是在编译器程序之前运行的独立程序。现代编译器内置了预处理器步骤,但在解析实际C代码之前,它仍然是一个单独的步骤。

答案 2 :(得分:0)

让我以另一种方式提出这个问题。

printf()是一个内置的标准库函数,它将格式化的输出发送到stdout(您的控制台屏幕)。 printf()函数调用在程序运行期间执行。语法看起来像这样。

int printf(const char *format, ...)

但是你的这个程序在编译之前用你的宏替换了printf()函数。

void fun(){
    #define printf(a, b) printf(a, b*2)
}
void main() {
   int x = 20;
   fun();
   x = 10;
   printf("%d", x);
}

所以会发生什么,在编译之前,编译器用你自己的用户定义的宏函数用两个参数替换内置函数调用:

  1. a =“%d”格式说明符和
  2. b = x = 10的值。
  3. 所以x * 2的值= 20