C语言补充-分文件编程和条件编译

:D

C语言的编译过程

从.c文件得到.exe文件大体上分为以下三个步骤:

  1. 预处理
  2. 编译
  3. 链接

预处理是指进行一些复制粘贴操作,比如#include "..."的文件复制粘贴,还有宏的展开

编译是指把预处理得到的暂时的.c文件编译为二进制文件,编译之后生成.o文件

链接是指把多个编译得到的源文件和系统组件(我也不知道是什么)全都打包起来,形成可执行文件

gcc基本用法

gcc是一个编译器+链接器(但是我们通常称它为编译器

命令gcc --help为显示帮助,可以快速查询各选项的功能

命令格式:

1
gcc [选项] [文件名]

下面是gcc常用的选项

  • -o

    gcc test.c -o test设置输出的文件为test.exe(如果不设置,默认a.exe)

  • -c

    仅编译,不链接

    例如gcc -c test.c 输出test.o文件

  • -S

    gcc -S test.c

    汇编

  • -E

    预处理

    直接gcc -E test.c似乎会把结果输出到终端,要输出到文件应该用gcc -E test.c -o test.i

  • -I

    指定头文件地址(如果头文件不在当前文件夹里面就需要用这个

  • -O1 -O2 -O3

    编译优化

分文件编程

使用gcc实现

有一个主文件,包含 main函数

如果要将其它函数的实现写在其他文件中,需要一个头文件function.h头文件里面写函数的声明,和头文件这个名字相同的.c文件(function.c)里面写函数的实现。

编译有两种方法

  • 直接一次性编译全部文件生成可执行文件

    1
    gcc [所有.c文件]

    选择.c文件的时候支持通配符,比如要编译这个文件夹里所有的*.c文件可以

    1
    gcc *.c

  • 先编译单个文件再链接

    这样做的好处是当修改了多个文件中的一个时,其他文件不必重新编译,适用于文件较多的情况。

预处理命令

以下是一些常用的预处理命令,用来控制哪些代码参加编译,哪些不参加

  • #define

  • #undef 取消定义,因此这个宏的作用域在#define和#undef之间

  • #ifdef

  • #ifndef if not define

  • #if

  • #elif

  • #else

  • #endif

  • defined

    用法:

    1
    #if defined(关键字)

    这么看似乎和#ifdef没啥区别,但是这个可以用来判断多个条件(用&&,||连接),并且可以用在#elif 后面


if-elseif-else-endif:

1
2
3
4
5
6
7
#ifdef (or #if or #ifndef) identity
code1
#elif
code2
#else
code3
#endif

#ifndef用法类似

实用的例子

目前都是写一些小代码,对我来说实用一些的就只有这个了吧:

写代码调试的时候,如果要输出中间结果经常会把代码改的乱七八糟,提交的时候删起来比较麻烦,但是如果把输出中间结果的代码写到条件编译里面,例如:

1
2
3
#ifdef DEBUG
//option
#endif

而在调试的时候编译加上选项-DDEBUG

1
gcc -DDEBUG test.c

就相当于在代码里面定义了DEBUG(上面的"DEBUG"可以换成任何单词)


[参考资料]

[1] C语言中.h和.c文件解析

[2] GCC 编译命令