C 预处理器包含指令
C Preprocessor include directive
当我包含另一个源(即 stdio.h
)时,预处理器足够智能,可以仅包含我在代码中使用的函数?
示例:假设这个小程序只包含我正在使用的内容以及 printf 函数使用的内容,递归地包含它们,但是更大的程序呢?
#include <stdio.h>
int main(void) {
printf("Hello World\n");
return 0;
}
没有。反之:
#include
执行文本替换:它打开文件并将其所有1 内容复制到您的主 C 文件中。在此过程中,它执行包含文件中的所有预处理器指令。除其他事项外,这意味着它将递归地包含 header.
中 #include
d 的所有文件
#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
函数之一),因为它完全由编译器指令组成,没有任何内容否则。
当我包含另一个源(即 stdio.h
)时,预处理器足够智能,可以仅包含我在代码中使用的函数?
示例:假设这个小程序只包含我正在使用的内容以及 printf 函数使用的内容,递归地包含它们,但是更大的程序呢?
#include <stdio.h>
int main(void) {
printf("Hello World\n");
return 0;
}
没有。反之:
#include
执行文本替换:它打开文件并将其所有1 内容复制到您的主 C 文件中。在此过程中,它执行包含文件中的所有预处理器指令。除其他事项外,这意味着它将递归地包含 header.
#include
d 的所有文件
#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
函数之一),因为它完全由编译器指令组成,没有任何内容否则。