强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

C/C++ Linux 开发教程(GCC + CMake) / 01 — C 语言简介与 GCC 环境搭建

C 语言简介与 GCC 环境搭建

1. C 语言历史

C 语言诞生于 1972 年,由 Dennis Ritchie 在贝尔实验室开发,最初用于重写 UNIX 操作系统内核。经过数十年发展,C 语言已成为世界上最重要的编程语言之一。

标准年份说明
K&R C1978《The C Programming Language》定义的非正式标准
ANSI C (C89)1989第一个正式标准,也称 C89 / C90
C991999引入 // 注释、变长数组、stdint.h
C112011多线程支持 _Thread_local、泛型选择 _Generic
C172017Bug 修复版本,无新增特性
C232023最新标准,引入 nullptrconstexpr、属性语法等

💡 提示: GCC 默认使用的标准版本取决于 GCC 版本。建议显式指定 -std= 选项以确保可移植性。


2. C 语言特点

C 语言之所以经久不衰,源于以下核心特点:

  • 底层控制: 可直接操作内存(指针)、访问硬件地址
  • 执行效率: 编译后生成原生机器码,性能接近汇编
  • 可移植性: 一次编写,到处编译——从嵌入式单片机到超级计算机
  • 简洁语法: 关键字仅 32 个(C89),语法精炼
  • 生态丰富: 操作系统、数据库、编译器等基础设施几乎全部用 C 编写

⚠️ 注意: C 语言没有垃圾回收、没有内置的边界检查、没有面向对象支持。它赋予程序员极大的自由,也要求程序员对内存管理负责。


3. 安装 GCC

3.1 Linux

# Debian / Ubuntu
sudo apt update
sudo apt install build-essential

# Fedora
sudo dnf install gcc gcc-c++ make

# Arch Linux
sudo pacman -S base-devel

3.2 macOS

# 安装 Xcode Command Line Tools
xcode-select --install

# 或通过 Homebrew 安装 GCC
brew install gcc

3.3 Windows

推荐使用 MSYS2

# 安装 MSYS2 后,在 MSYS2 终端执行
pacman -S mingw-w64-ucrt-x86_64-gcc

安装完成后,将 C:\msys64\ucrt64\bin 添加到系统 PATH

3.4 验证安装

gcc --version

输出示例:

gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
Copyright (C) 2023 Free Software Foundation, Inc.

4. 第一个 C 程序

创建文件 hello.c

#include <stdio.h>

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

编译并运行:

gcc -o hello hello.c
./hello

输出:

Hello, World!

代码解析

说明
#include <stdio.h>引入标准 I/O 库头文件
int main(void)程序入口点,返回类型为 intvoid 表示不接受命令行参数
printf(...)标准输出函数,\n 为换行符
return 0返回 0 表示程序正常退出

💡 提示: main 函数返回 0 是操作系统约定。返回非零值通常表示程序异常退出。


5. 编译流程

C 程序从源代码到可执行文件,经历四个阶段:

源代码(.c) → 预处理 → 编译 → 汇编 → 链接 → 可执行文件

我们可以用 GCC 分步查看每个阶段:

5.1 预处理 (Preprocessing)

gcc -E hello.c -o hello.i

展开所有 #include#define 宏等。hello.i 文件通常非常庞大。

5.2 编译 (Compilation)

gcc -S hello.c -o hello.s

生成汇编代码(.s 文件)。

5.3 汇编 (Assembly)

gcc -c hello.c -o hello.o

生成目标文件(.o),包含机器码但尚未链接外部库。

5.4 链接 (Linking)

gcc hello.o -o hello

将目标文件与库文件链接,生成最终可执行文件。

阶段输入输出命令
预处理.c.igcc -E
编译.i / .c.sgcc -S
汇编.s.ogcc -c
链接.o + 库可执行文件gcc *.o

6. GCC 常用选项

选项说明示例
-o <file>指定输出文件名gcc -o prog main.c
-Wall启用所有常用警告gcc -Wall main.c
-Wextra启用额外警告gcc -Wall -Wextra main.c
-Werror将警告视为错误gcc -Werror main.c
-O0不优化(默认,便于调试)gcc -O0 main.c
-O1 / -O2 / -O3优化级别递增gcc -O2 main.c
-Os优化体积gcc -Os main.c
-std=c99指定 C 标准gcc -std=c99 main.c
-std=c11使用 C11 标准gcc -std=c11 main.c
-std=c17使用 C17 标准gcc -std=c17 main.c
-g生成调试信息gcc -g main.c
-pedantic严格遵循标准gcc -pedantic main.c
-I<dir>添加头文件搜索路径gcc -I./include main.c
-L<dir>添加库文件搜索路径gcc -L./lib main.c
-l<lib>链接指定库gcc main.c -lm

⚠️ 注意: 养成使用 -Wall -Wextra 的习惯,许多潜在 bug 会在编译时被发现。


7. 编辑器 / IDE 配置

7.1 VSCode

  1. 安装扩展 C/C++
  2. 安装扩展 C/C++ Extension Pack
  3. Ctrl+Shift+PC/C++: Edit Configurations (UI),设置编译器路径和标准

.vscode/tasks.json 示例:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "gcc",
            "args": [
                "-Wall", "-Wextra", "-std=c17",
                "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "group": { "kind": "build", "isDefault": true }
        }
    ]
}

7.2 CLion

CLion 使用 CMake 管理项目,自动生成 CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(my_project C)

set(CMAKE_C_STANDARD 17)

add_executable(my_project main.c)

8. 编译多个文件

当项目由多个 .c 文件组成时,需要分别编译再链接:

gcc -c main.c -o main.o
gcc -c utils.c -o utils.o
gcc main.o utils.o -o myapp

或者一步到位:

gcc main.c utils.c -o myapp

💡 提示: 大型项目中建议使用 makeCMake 管理编译流程,避免重复编译未修改的文件。

使用 Makefile 简化

CC = gcc
CFLAGS = -Wall -Wextra -std=c17 -g

myapp: main.o utils.o
	$(CC) $(CFLAGS) -o $@ $^

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f *.o myapp

9. C vs C++:如何选择?

维度CC++
编译器gccg++
文件扩展名.c.cpp / .cc
面向对象不支持完整支持
标准库精简(libc丰富(STL)
适用场景操作系统、嵌入式、驱动游戏引擎、GUI、大型应用
学习曲线较低(语法简单)较高(特性繁多)
内存管理手动(malloc/free手动 + RAII + 智能指针

建议:

  • 初学者: 先学 C,理解指针和内存管理
  • 系统编程: 使用 C(Linux 内核、嵌入式固件)
  • 应用开发: 使用 C++(利用 STL 和面向对象)

10. 实际场景:编译一个小型项目

假设项目结构如下:

project/
├── main.c
├── math_utils.c
└── math_utils.h

math_utils.h

#ifndef MATH_UTILS_H
#define MATH_UTILS_H

int add(int a, int b);
int multiply(int a, int b);

#endif

math_utils.c

#include "math_utils.h"

int add(int a, int b)
{
    return a + b;
}

int multiply(int a, int b)
{
    return a * b;
}

main.c

#include <stdio.h>
#include "math_utils.h"

int main(void)
{
    int x = 3, y = 5;
    printf("%d + %d = %d\n", x, y, add(x, y));
    printf("%d * %d = %d\n", x, y, multiply(x, y));
    return 0;
}

编译运行:

gcc -Wall -Wextra -std=c17 -o myapp main.c math_utils.c
./myapp

输出:

3 + 5 = 8
3 * 5 = 15

11. 常见编译错误

错误信息原因解决
undefined reference to 'main'缺少 main 函数添加 int main(void) { ... }
fatal error: stdio.h: No such file未安装 C 标准库开发包sudo apt install build-essential
implicit declaration of function未声明函数原型添加函数声明或 #include 对应头文件
segmentation fault内存访问违规检查指针和数组越界

12. 扩展阅读