C 预处理器包含指令

C Preprocessor include directive

当我包含另一个源(即 stdio.h)时,预处理器足够智能,可以仅包含我在代码中使用的函数?

示例:假设这个小程序只包含我正在使用的内容以及 printf 函数使用的内容,递归地包含它们,但是更大的程序呢?

#include <stdio.h> 

int main(void) {
   printf("Hello World\n"); 
   return 0;
}

没有。反之:

#include 执行文本替换:它打开文件并将其所有1 内容复制到您的主 C 文件中。在此过程中,它执行包含文件中的所有预处理器指令。除其他事项外,这意味着它将递归地包含 header.

#included 的所有文件

#include 不知道也不关心您最终使用了包含文件的哪一部分。


1 如前所述,预处理器指令 在包含的文件中执行。这可以修改包含的内容。例如,假设以下 header 文件 header.h:

#ifndef HEADER_H
#define HEADER_H

#ifdef NDEBUG
#  define LOG(...) ((void) 0)
#else
#  define LOG(...) log_message(__FILE__, __LINE__, __VA_ARGS__)

inline void log_message(const char* filename, int line, ...) {
    // Logging code omitted for brevity.
}
#endif

// other stuff

#endif

现在,如果您的 main.c 文件如下所示:

#define NDEBUG
#include "header.h"

int main(void) {
    // …
    LOG("hello");
}

... 然后,经过预处理后,您的 main.c 文件将如下所示(我省略了一些不相关的内容):

# 1 "main.c"

# 1 "./header.h" 1




# 13 "./header.h"

// other stuff


# 3 "main.c" 2

int main(void) {
    // …
    ((void) 0);
}

……换句话说,只包括了header.h中对应于#ifdef NDEBUG的部分,而不是#else子句中的部分。如果我们在没有定义 NDEBUG 的情况下包含 header.h,那么包含的 header 代码将包含 log_message.

的定义

正如其他人所说,#include 将逐字粘贴您要定位的整个文件。但是,您通常包括 headers,它看起来像

extern int a (int b);

extern char * c (void);

static inline int d (int e, int f) {
    ...
}

extern void * g (void * h);

...

上面的代码占用的内存恰好为零(除非你开始使用 inline 函数之一),因为它完全由编译器指令组成,没有任何内容否则。