C
This commit is contained in:
294
C/Ccompile.md
Normal file
294
C/Ccompile.md
Normal file
@@ -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 背后的逻辑
|
||||
|
||||
你选一个,我直接给你干到“明白为止”。
|
||||
372
C/数据类型.md
Normal file
372
C/数据类型.md
Normal file
@@ -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 <stdbool.h>
|
||||
|
||||
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 <stdint.h>
|
||||
```
|
||||
|
||||
## 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`**
|
||||
|
||||
你选一个,我接着往下带你。
|
||||
Reference in New Issue
Block a user