RayanHayle 深度解析

CS3157 Advanced Programming - 从零开始的完整学习指南

1. 前置知识解释 (From Scratch)

在打开任何 .c 文件之前,请确保你理解以下概念。

🧠 内存模型

栈 (Stack): 自动管理,函数结束自动释放。

堆 (Heap): 手动管理 (malloc/free)。忘记释放 = 内存泄漏。

👆 指针 (Pointers)

int *p = &x;p 存储 x 的地址。

*p 获取指向的值,&x 获取地址。

📦 结构体 (Struct)

把多种类型打包成一个自定义类型。

struct Student { char name[50]; int age; };
🔀 进程 (Process)

fork() 创建子进程。exec() 替换当前进程。wait() 等待子进程结束。

🌐 Socket (网络)

服务器: socket → bind → listen → accept

客户端: socket → connect

📝 HTTP 协议

请求: GET /path HTTP/1.0

响应: HTTP/1.0 200 OK + Headers + Body

2. 工具箱范围界定

头文件 用途 常用函数
stdio.h I/O printf, scanf, fopen, fgets
stdlib.h 内存/转换 malloc, free, atoi, exit
string.h 字符串 strcpy, strlen, strstr, memcpy
unistd.h 系统调用 fork, exec, read, write
sys/socket.h 网络 socket, bind, listen, accept

自定义库: mylist.h (链表), mdb.h (数据库记录)

3. 文件详解

Lab 1: C 语言入门 基础

gcd.c & prime.c

使用辗转相除法计算最大公约数,并判断素数。

int gcd(int a, int b) {
    while (b != 0) { int t = b; b = a % b; a = t; }
    return a;
}

convert.c

使用位操作将整数转换为二进制: (n >> i) & 1

Lab 2: 动态内存 基础

isort.c

动态分配数组,使用 qsort 排序。关键是提供比较函数指针

twecho.c

复制 argv,大写转换,关键是双重释放:先释放每个字符串,再释放指针数组。

Lab 3: 链表库 核心

mylist.h / mylist.c

通用链表,使用 void *data 实现泛型。核心函数: addFront, popFront, traverseList

traverseList 接收函数指针,实现了 C 语言的多态。

Lab 4-5: 数据库工具 核心

mdb-lookup.c

从二进制文件加载 MdbRec 到链表,使用 strstr 搜索匹配项。

Lab 6: 网络编程 网络

mdb-lookup-server.c

TCP 服务器: socket → bind → listen → accept → recv/send → close。

重点: 使用 fdopen 将 socket 包装成 FILE*,便于用 fgets 读取。

http-client.c

HTTP 客户端: 构建 GET 请求,发送,解析响应头 (找 \r\n\r\n),保存 Body。

Lab 7: HTTP 服务器 网络

http-server.c

静态文件服务 + 反向代理。根据 URL 路由请求到不同处理逻辑。

4. 条件反射训练

🚨 看到 malloc / free
反射: 对应的 free 在哪里?检查返回值是否为 NULL
检查: 异常分支是否有提前 return 导致内存泄漏?
🔗 看到 struct Node { *next; }
反射: 这是链表。头节点可能是 NULL
检查: 遍历 while (curr),插入/删除边界条件。
🔄 看到 fork()
反射: pid == 0 是子进程,pid > 0 是父进程。
检查: 父进程有 wait/waitpid 吗?小心僵尸进程!
🌐 看到 bind / listen / accept
反射: 这是服务器端。
检查: htons/htonl 字节序转换了吗?每个系统调用检查返回值了吗?