From 466080952b2f9c8453b1495d25611fa48ac4d9af Mon Sep 17 00:00:00 2001 From: e2hang <2099307493@qq.com> Date: Tue, 23 Dec 2025 20:08:44 +0800 Subject: [PATCH] C --- C/Ccompile.md | 294 +++++++++++++++++++++++++++++++++++++++ C/数据类型.md | 372 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 666 insertions(+) create mode 100644 C/Ccompile.md create mode 100644 C/数据类型.md diff --git a/C/Ccompile.md b/C/Ccompile.md new file mode 100644 index 0000000..7bf4735 --- /dev/null +++ b/C/Ccompile.md @@ -0,0 +1,294 @@ +好,这个问题问得**非常本质**,而且一看就是你已经开始从“会写代码”往“懂工具链 / 懂底层”走了 👍 +我分三层给你捋清楚:**编译器有哪些 → 编译/汇编/链接的指令 → C 与 C++ 在编译层面的真实差异**。 + +--- + +## 一、主流 C / C++ 编译器版图(你必须认识的) + +### 1️⃣ GCC / G++ + +* **全名**:GNU Compiler Collection +* **支持语言**:C / C++ / Fortran / Go / Obj-C / … +* **命令**: + + * `gcc` → 主要用来编 C + * `g++` → 主要用来编 C++ +* **平台**:Linux / WSL / macOS / *nix +* **特点**: + + * 工业级事实标准 + * 参数多、控制力极强 + * 对 ABI、链接、底层非常“真实” + +📌 **重点**: +`gcc` 和 `g++` **底层是同一个编译器**,区别在: + +* 默认语言不同 +* 是否自动链接 `libstdc++` +* 是否启用 C++ 语义(name mangling、异常等) + +--- + +### 2️⃣ Clang / Clang++ + +* **LLVM 系列** +* **命令**: + + * `clang` + * `clang++` +* **平台**:Linux / macOS / Windows +* **特点**: + + * 错误提示极其友好(新手 + 老手都爱) + * 编译速度快 + * AST、静态分析能力强 + +📌 **现实情况**: + +* macOS 上的 `gcc` 实际就是 `clang` +* 现代 C++ 项目大量使用 clang + +--- + +### 3️⃣ MSVC(Windows 专属) + +* **微软官方编译器** +* **命令**: + + * `cl.exe` +* **特点**: + + * Windows ABI 官方实现 + * C++ 标准支持偏慢但稳定 + * 和 Visual Studio 深度绑定 + +📌 **注意**: + +* MSVC ≠ GCC / Clang +* 一些 GCC 的参数 **在 MSVC 上完全不存在** + +--- + +### 4️⃣ 其他你只需“知道存在”的 + +| 编译器 | 用途 | +| --------------- | -------------- | +| TinyCC (tcc) | 极快、教学 | +| Intel ICC / ICX | 性能优化 | +| ARM GCC | 嵌入式 | +| MinGW | Windows 上的 GCC | + +--- + +## 二、C / C++ 编译的**完整流程**(不是一句 gcc) + +### 🧠 真相:**编译 = 4 个阶段** + +```text +源代码 + ↓ +预处理(cpp) + ↓ +编译(cc1 / clang) + ↓ +汇编(as) + ↓ +链接(ld) +``` + +--- + +## 三、你问的重点①:**“各种指令”是哪些?** + +### 1️⃣ 预处理指令(只和文本有关) + +```bash +gcc -E a.c +``` + +| 指令 | 作用 | +| ---------------- | ---- | +| `#include` | 文本展开 | +| `#define` | 宏替换 | +| `#ifdef` / `#if` | 条件编译 | + +📌 **关键点**: + +* C 和 C++ **完全一样** +* 预处理器不知道“类型”“函数”“类” + +--- + +### 2️⃣ 编译阶段指令(最核心) + +#### 基础用法 + +```bash +gcc -c a.c # 只编译,不链接 +g++ -c a.cpp +``` + +#### 常用编译参数 + +| 参数 | 含义 | +| -------------------------------- | ---- | +| `-std=c11 / c17 / c++17 / c++20` | 标准 | +| `-Wall -Wextra` | 警告 | +| `-O0 -O2 -O3` | 优化 | +| `-g` | 调试信息 | +| `-fno-omit-frame-pointer` | 调试友好 | +| `-fsanitize=address` | ASan | + +📌 **重点差异**: + +* C++ 会启用: + + * **函数重载** + * **模板实例化** + * **名字修饰(name mangling)** + +--- + +### 3️⃣ 汇编层(你开始接触底层时很重要) + +```bash +gcc -S a.c +g++ -S a.cpp +``` + +📌 差异点: + +* C++ 生成的汇编: + + * 函数名会被改写(`_Z3addii`) + * 有构造 / 析构 / 异常展开 +* C: + + * 函数名基本原样 + +--- + +### 4️⃣ 链接阶段(很多“玄学错误”的源头) + +```bash +gcc a.o b.o -o app +g++ a.o b.o -o app +``` + +#### **最重要的差异** + +| 行为 | gcc | g++ | +| ----------------- | --- | --- | +| 自动链接 libstdc++ | ❌ | ✅ | +| 支持 new / iostream | ❌ | ✅ | + +📌 经典坑: + +```bash +gcc main.cpp +# undefined reference to std::cout +``` + +因为 **gcc 不自动链接 C++ 标准库** + +--- + +## 四、你问的重点②:**C 与 C++ 在“编译器层面”的差异** + +### 1️⃣ 语言前端不同 + +| 项目 | C | C++ | +| ---- | -- | --- | +| 类型系统 | 简单 | 极复杂 | +| 模板 | ❌ | ✅ | +| 函数重载 | ❌ | ✅ | +| 名字修饰 | ❌ | ✅ | + +📌 本质: + +> **同一个编译器,不同“语言前端”** + +--- + +### 2️⃣ Name Mangling(超级重要) + +```cpp +int add(int a, int b); +``` + +| 语言 | 符号名 | +| --- | ---------- | +| C | `add` | +| C++ | `_Z3addii` | + +所以你见过: + +```cpp +extern "C" { + void foo(); +} +``` + +👉 **是为了让 C++ 用 C 的符号规则** + +--- + +### 3️⃣ 运行时支持完全不同 + +| 项目 | C | C++ | +| ----- | ---- | --------- | +| 构造/析构 | ❌ | ✅ | +| RTTI | ❌ | ✅ | +| 异常 | ❌ | ✅ | +| 标准库 | libc | libstdc++ | + +📌 所以: + +* C 程序 = **非常薄** +* C++ 程序 = **编译器 + 运行时体系** + +--- + +### 4️⃣ ABI 差异(工程级别) + +* C ABI:**几乎永远稳定** +* C++ ABI: + + * 不同编译器、不同版本可能不兼容 + * 这就是为什么库常用 **C 接口** + +--- + +## 五、给你一个“认知升级总结” + +> 🔥 **C 是“能跑就行的语言”** +> 🔥 **C++ 是“需要编译器深度参与的语言”** + +所以你会发现: + +* 学 C → 多学 **内存、指针、汇编** +* 学 C++ → 多学 **编译模型、ABI、链接、对象模型** + +--- + +## 六、下一步我可以怎么继续帮你? + +你现在这个问题,**已经明显在向系统级程序员靠拢了**。 +我可以继续给你: + +1️⃣ 用 **同一段代码** 对比 + +* gcc / g++ / clang / msvc +* 汇编输出差异 + +2️⃣ 系统讲一遍 + +* **C++ 对象在内存里的真实布局** +* vtable / 构造顺序 / 析构顺序 + +3️⃣ 专门讲 + +* **链接错误为什么那么玄学** +* undefined reference 背后的逻辑 + +你选一个,我直接给你干到“明白为止”。 diff --git a/C/数据类型.md b/C/数据类型.md new file mode 100644 index 0000000..35383db --- /dev/null +++ b/C/数据类型.md @@ -0,0 +1,372 @@ +好,这个问题问得**非常对味** 👍 +你现在这个阶段,就该把 **C 的类型系统一次性“扫干净”**,否则后面看 SDL / 源码 / 系统接口永远会被各种 `uint32_t`、`size_t`、`intptr_t` 绊住。 + +下面我给你一份 **「工程级·C语言数据类型大全」**,按**来源 + 本质**来分,保证你以后看到一个类型就知道它“从哪来、干嘛用、多大”。 + +--- + +# 一、C 语言内建基本类型(语言核心) + +> 这是 **C 语法本体**,不需要 `#include` + +## 1️⃣ 整型(Integer types) + +### (1)字符整型 + +```c +char // 至少 8 位(实现定义) +signed char // 至少 8 位 +unsigned char // 至少 8 位 +``` + +⚠️ 注意: + +* `char` ≠ `signed char` ≠ `unsigned char` +* `char` 是否有符号是**实现定义** + +--- + +### (2)短整型 + +```c +short +short int +signed short +signed short int + +unsigned short +unsigned short int +``` + +* **至少 16 位** +* 常见:16 位 + +--- + +### (3)整型(最常用) + +```c +int +signed int +unsigned int +``` + +* **至少 16 位** +* 常见: + + * 32 位(现代系统) + +--- + +### (4)长整型 + +```c +long +long int +signed long +unsigned long +``` + +* **至少 32 位** +* 常见: + + * Linux x64:64 位 + * Windows x64:32 位(LLP64) + +--- + +### (5)长长整型(C99) + +```c +long long +long long int +signed long long +unsigned long long +``` + +* **至少 64 位** +* 基本稳定为 64 位 + +--- + +## 2️⃣ 浮点类型 + +```c +float // 单精度 +double // 双精度 +long double // 扩展精度(实现定义) +``` + +常见: + +| 类型 | 位数 | +| ----------- | ------------- | +| float | 32 | +| double | 64 | +| long double | 80 / 128 / 64 | + +--- + +## 3️⃣ 布尔类型(C99) + +```c +#include + +bool // 实际是 _Bool +_Bool +``` + +* `_Bool` 是内建类型 +* `bool` 是宏别名 + +--- + +## 4️⃣ 空类型 + +```c +void +``` + +用途: + +* 无返回值 +* 泛型指针 `void*` + +--- + +# 二、修饰符(类型“调味料”) + +这些**不是独立类型**,而是修饰已有类型: + +```c +signed +unsigned +short +long +``` + +合法组合例子: + +```c +unsigned long long int +signed short +long double +``` + +非法组合: + +```c +unsigned float ❌ +short double ❌ +``` + +--- + +# 三、固定宽度整数(`stdint.h`,**强烈推荐**) + +> 你看到的 `int64_t`、`uint32_t` 全在这 + +```c +#include +``` + +## 1️⃣ 精确宽度(一定存在才定义) + +```c +int8_t uint8_t +int16_t uint16_t +int32_t uint32_t +int64_t uint64_t +``` + +✔ **最常用、最安全** + +--- + +## 2️⃣ 至少 N 位 + +```c +int_least8_t +int_least16_t +int_least32_t +int_least64_t +``` + +--- + +## 3️⃣ 最快类型 + +```c +int_fast8_t +int_fast16_t +int_fast32_t +int_fast64_t +``` + +--- + +## 4️⃣ 指针等宽整数(系统编程必备) + +```c +intptr_t +uintptr_t +``` + +👉 能安全存放指针的整数 + +--- + +## 5️⃣ 最大整数类型 + +```c +intmax_t +uintmax_t +``` + +--- + +# 四、常见 typedef(标准库里“看起来像关键字的东西”) + +## 1️⃣ `stddef.h` + +```c +size_t // sizeof 的结果类型(无符号) +ptrdiff_t // 指针差值(有符号) +nullptr_t // C23 +``` + +--- + +## 2️⃣ `limits.h` / `stdint.h` + +```c +CHAR_BIT // 一个字节多少 bit(通常 8) +INT_MAX +UINT_MAX +``` + +--- + +## 3️⃣ `sys/types.h`(POSIX) + +```c +ssize_t // size_t 的有符号版 +off_t // 文件偏移 +pid_t // 进程 ID +``` + +--- + +# 五、字符 & 文本相关类型 + +```c +char // 字节 / UTF-8 +wchar_t // 宽字符(平台相关) +``` + +C11 还支持: + +```c +char16_t +char32_t +``` + +(但在 C 里用得不多) + +--- + +# 六、非标准但“到处都是”的别名(你问的 uint / uchar) + +⚠️ **这些不是 C 标准!** + +常见于: + +* Windows +* 嵌入式 +* 老代码 +* 游戏 / 引擎 + +```c +typedef unsigned int uint; +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned long ulong; +typedef long long int64; +typedef unsigned long long uint64; +``` + +👉 **完全是项目自定义** +👉 **千万别假设它们存在** + +--- + +# 七、复合类型(不是基本类型,但必须知道) + +```c +struct +union +enum +``` + +以及: + +```c +typedef +``` + +--- + +# 八、函数 / 指针 / 数组“伪类型” + +```c +int* p; +int (*fp)(int); +int arr[10]; +``` + +它们不是新类型,而是**类型构造方式** + +--- + +# 九、一张“终极速查表”(你该背的) + +### ✅ 必背 + +* `char` +* `int` +* `long` +* `long long` +* `float` +* `double` +* `void` +* `size_t` +* `intptr_t` +* `int32_t / uint32_t` +* `int64_t / uint64_t` +* `bool` + +### ❌ 不该依赖 + +* `uint` +* `uchar` +* `DWORD` +* `BYTE` + +--- + +## 最后一句工程建议(很重要) + +> **写现代 C:** +> +> * 用 `stdint.h` +> * 用 `size_t` +> * 少猜位宽 +> * 不造轮子 typedef + +如果你愿意,下一步我可以帮你做一件事之一: + +* 🔍 把 **SDL 里所有 typedef 拆给你看** +* 🧠 给你出 **“看到类型 → 推断平台行为”训练题** +* 🧱 教你 **自己写一个干净的 `types.h`** + +你选一个,我接着往下带你。