C 语言学习笔记 02 - CMake 项目结构

新建项目

打开 CLion,创建新项目,选择 C Executable (C 可执行程序)

创建项目

除去项目位置外,下面的两个选项分别为 C 语言标准与库类型。

与其他语言仅有一种独立语言标准不同,C 语言有着不同的标准,例如 CLion 中列举的 C90、C99、C23 等。其中 C99 使用最为广泛。你可以在[这里](https://en.wikipedia.org/wiki/C_(programming_language#C99)查看这些语言标准。

语言标准的支持取决于编译器的支持程度,例如「msvc」所支持的语言标准就少于 MinGW。

此处我们选择 C99 作为语言标准。

库类型分别有两种类型,静态与动态。

用通俗易懂的话来说,动态库就像一个书店,而静态库则是图书馆。每个人都能从书店里直接买到属于自己的那本书,而图书馆只能让一个人同时拿到对应的一本书。

静态库 (.a/.lib) 在编译期已经成形,所有相关代码都封装在这个库中,没有额外开销,但大小相比使用了动态库的应用大得多。并且由于是静态的库,更新时「牵一发而动全身」,需要全量更新。

动态库 (.so/.dll/.dylib) 则是封装了所需代码,在运行时而非编译时被其他程序引用,动态链接至其他程序中,有点类似于引用第三方库,能够增量更新,在无需重新编译的情况下更新。

此处我们选择 static 作为库类型。

等待项目初始化完成后,我们可以看见 CLion 自动生成了 Hello World 代码,下面介绍左侧 Project 中的文件与文件夹。

项目初始化完成

main.c => 程序的入口点

CMakeLists.txt => CMake 配置文件

其中两个以cmake 开头的文件夹分别对应着不同的编译链的相关文件,此处分别为 Visual Studio 和 MinGW,这里后者的编译链是笔者自行添加的,欲修改编译链,可以打开 Settings -> Build, Execution, Deployment -> CMake 修改 Profile 中的 Toolchain 为 MinGW。就笔者个人而言,推荐你使用 MinGW。

请注意,在将你的 C 项目上传到诸如 GitHub 的代码管理平台时,你不必上传这些文件夹,就像 Gradle 的 gradle 文件夹一样,它们会在编译时自动生成,文件夹中存放着中间文件。

语言标准

前文提到了 C 语言的标准,但数字上的差异很难让人体会到区别,下面举一个简单的例子方便理解。

首先,我们先写一段简单的 for 循环:

#include <stdio.h>

int main() {
    for (int i = 0; i < 12; ++i) {
        printf("Ryouran! Nijigasaki!\n");
    }

    return 0;
}

我们将 CMakeLists.txt 中的 set(CMAKE_C_STANDARD 99) 中的 99 修改为 90,并按照 CLion 提示 Reload changes。等待重载完成后,返回 main.c 查看这段 for 循环,会得到以下提示:

语言标准切换后报错

CLion 提示我们 GCC 不允许在 for 循环中声明变量。在 C90 标准下,一个正确的 for 循环要求我们预先声明变量:

#include <stdio.h>

int main() {
    int i;
    
    for (i = 0; i < 12; ++i) {
        printf("Ryouran! Nijigasaki!!\n");
    }

    return 0;
}

前文我们提到过,设置不同的标准并不代表编译链就支持这个标准。相反,使用不同的编译链你所选择的标准也不一定完全有效,例如「神奇」的 msvc。当我们将编译工具链切换至 msvc 后,C90 标准下不允许的写法竟然成功通过了编译,直接运行。这是因为 msvc 是 C++ 的编译器,本身就兼容这样的写法。至此,我们大致讲解了项目中相关的文件,环境配置也大抵完成。

在环境配置完成之后,下一节中我们将介绍如何调试 C 语言程序。

comments powered by Disqus