C 语言内存操作函数
更新时间:2026-08-26。本文是
languages/c/主题高手层的骨架文档(占位),完整展开将在后续批次补齐。
本文要回答的问题
memcpy和按字段赋值有什么区别?memmove又解决了什么?- 把结构体
memset成 0 是万能的吗? - "严格别名"规则为什么会坑到人?
一、内存操作函数族
| 函数 | 作用 | 注意 |
|---|---|---|
memcpy(dst, src, n) | 按字节拷贝 n 字节 | 区域不能重叠 |
memmove(dst, src, n) | 拷贝 n 字节 | 允许重叠(内部判断方向) |
memset(p, c, n) | 把 n 字节设为 c | 常用于清零结构体 |
memcmp(a, b, n) | 逐字节比较 | 比 strcmp 快(不遇 0 停) |
memcpy 常被编译器内联成高效指令序列(甚至 SIMD),性能远好于手写循环。重叠区域必须用 memmove,这是最常见的误用点。
二、字节视角与别名
memset(&obj, 0, sizeof(obj))清零结构体是惯例,但对浮点、指针清零并不保证是"合法空值"(指针通常 OK,但标准只保证整型 0)。- 严格别名规则:不同类型的指针不能指向同一内存做读写(除非
char*)。违反它,-O2下编译器可能按假设优化出错误结果。
c
int x = 5;
float *f = (float *)&x; /* 危险:违反严格别名 */正确做法:用 memcpy 做"类型双关"(type punning),编译器会正确对待。
三、与入门层的衔接
- 指针运算与字节地址,见 指针运算。
- 通用字节缓冲区与 void*,见 void 指针。
- 二进制文件读写中内存操作的应用,见 fread/fwrite。
一句话总结
memcpy/memset 是"按字节干活"的底层工具:重叠用 memmove、双关用 memcpy,尊重严格别名规则,优化器才不会在背后坑你。
本文为骨架文档:核心结构已就位,示例代码与实测数据将在后续批次补齐。