宏工作原理以及典型面试10问

宏工作原理

以hello word程序为例来看看,将下述代码存成hello.c

#include <stdio.h>
#define STR "hello world"
/*这是一个hello word程序*/
int main(void)
{
    
    
    printf("%s",STR);
    return 0;
}

为了说明问题,这里用下面的命令进行显式预处理,将得到hello.i文件,实际编译过程中,会自动完成。

//gcc -E 生成预处理文件
gcc -E hello.c -o hello.i

来大致看看hello.i文件

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
#删除很多行
.......
extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
# 912 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));

extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;

extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 942 "/usr/include/stdio.h" 3 4

# 2 "hello.c" 2
# 4 "hello.c"
int main(void)
{
    
    
    printf("%s","hello world");
    return 0;
}

上面这步操作做了三件事情:

  • 删除注释:删除所有注释。注释仅供程序员理解代码,注释对机器没有用。因此预处理器在预处理过程中会删除注释,因为注释在执行过程中是不需要的,也不会被执行。所以注释尽管写不影响程序的逻辑,当然写的过也未必是好事,过少也不是好事。个人理解一份好的代码应尽量少注释,应该通过合理的命名习惯,良好的编程风格来提高可读性,在一些关键复杂算法处则应清晰的加上注释。在hello.c中的注释 /这是一个hello word程序/ 在预处理后被删除掉了。
  • 文件包含:包含程序需要的所有文件。C语言中使用#include,这是预处理器的指令,告诉预处理器包含指定文件的内容。例如#include将告诉预处理器将stdio.h中所有的内容包含进来。也可以使用双引号-#include “stdio.h” 注意:如果使用尖括号,则在编译器包含路径中搜索文件。如果文件名用双引号包起来,则搜索路径将扩展为除了编译器包含路径外的当前目录下。
  • 宏展开替换:比如上例中宏STR在预处理时就被展开替换了。宏有两种常见形式:

1、不带参形式(有的地方也称对象形式object-like)。

#define PI 3.1415926f

2、带参形式(有的地方也称为函数形式function-like)。

#define SQUARE(x) ((x)*(x))

经典面试10问请阅读:宏工作原理以及典型面试10问

更多阅读:【为宏正名】for的妙用你想不到

猜你喜欢

转载自blog.csdn.net/weixin_45905650/article/details/108424672