C 语言内存函数全解析:从 memcpy 到 memcmp 的使用与模拟实现
目录memcpy的使用和模拟实现memmove的使用和模拟实现memset函数的使用memcpm函数的使用1.memcpy的使用和模拟实现1.1memcpy函数的使用//函数原型 void* memcpy(void* destination, const void* source, size_t num);void *是“万能入口”char *才是“字节搬运工”——按字节逐个拷贝函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。这个函数在遇到 \0 的时候并不会停下来。如果source和destination有任何的重叠复制的结果都是未定义的。memcpy函数不支持内存重叠拷贝使用举例#include stdio.h #include string.h int main() { int arr1[] { 1,2,3,4,5,6,7,8,9,10 }; int arr2[10] { 0 }; memcpy(arr2, arr1, 20); int i 0; for (i 0; i 10; i) { printf(%d , arr2[i]); } return 0; }输出结果1 2 3 4 5 0 0 0 0 0注意对于重叠的内存交给memmove来处理。1.2memcpy函数的模拟实现:#include assert.h void* my_memcpy(void* dest, void* src, size_t num) { assert(dest src); void* ret dest; while (num--) { *(char*)dest *(char*)src; dest (char*)dest 1; src (char*)src 1; } return ret; }memcpy之所以要把 void *转换成 char *是因为✅ void *不能做指针运算✅ 字节拷贝必须以「1 字节」为单位✅ 只有 char *能保证跨平台、标准、安全加入主函数测试#include stdio.h #include assert.h void* my_memcpy(void* dest, void* src, size_t num) { assert(dest src); void* ret dest; while (num--) { *(char*)dest *(char*)src; dest (char*)dest 1; src (char*)src 1; } return ret; } int main() { int arr1[10] { 1,2,3,4,5,6,7,8,9,10 }; my_memcpy(arr1, arr1 1, 5 * sizeof(int)); for (int i 0; i 10; i) { printf(%d , arr1[i]); } return 0; }测试结果2 3 4 5 6 6 7 8 9 102.memmove的使用和模拟实现2.1memmove的使用//函数原型 void * memmove ( void * destination, const void * source, size_t num );void *是“万能入口”char *才是“字节搬运工”——按字节逐个拷贝和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠就得使用memmove函数处理。使用举例#include stdio.h #include string.h int main() { int arr1[] { 1,2,3,4,5,6,7,8,9,10 }; memmove(arr1 2, arr1, 20); int i 0; for (i 0; i 10; i) { printf(%d , arr1[i]); } return 0; }输出结果1 2 1 2 3 4 5 8 9 102.2memmove的模拟实现#include assert.h void* my_memmove(void* dest,const void* src, size_t num) { assert(dest src); void* ret dest; if (dest src) { //前往后 while (num--) { *(char*)dest *(char*)src; dest (char*)dest 1; src (char*)src 1; } } else { //后往前 while (num--) { *((char*)dest num) *((char*)src num); } } return ret; }加入主函数测试#include stdio.h #include assert.h void* my_memmove(void* dest,const void* src, size_t num) { assert(dest src); void* ret dest; if (dest src) { //前往后 while (num--) { *(char*)dest *(char*)src; dest (char*)dest 1; src (char*)src 1; } } else { //后往前 while (num--) { *((char*)dest num) *((char*)src num); } } return ret; } int main() { int arr1[10] { 1,2,3,4,5,6,7,8,9,10 }; my_memmove(arr1, arr1 1, 5 * sizeof(int)); for (int i 0; i 10; i) { printf(%d , arr1[i]); } return 0; }测试结果2 3 4 5 6 6 7 8 9 10常见误区❌ 误区 1直接强转为 int*❌ 误区 2认为 void *可以直接用总结✅memmove 的核心不是“拷贝”而是“安全地按字节拷贝”✅void* 只负责“接收”不负责“运算”✅唯一正确的中间类型是 char*3.memset函数的使用//函数原型 void * memset ( void * ptr, int value, size_t num );memset是用来设置内存的将内存中的值以字节为单位设置成想要的内容。使用举例#include stdio.h #include string.h int main() { char str[] hello world; memset(str, x, 6); printf(%s\n, str); return 0; }输出结果xxxxxxworld4.memcmp函数的使用//函数原型 int memcmp ( const void * ptr1, const void * ptr2, size_t num );比较从ptr1和ptr2指针指向的位置开始向后的num个字节返回值如下使用举例#include stdio.h #include string.h int main() { char buffer1[] DWgaOtP12df0; char buffer2[] DWGAOTP12DF0; int n; n memcmp(buffer1, buffer2, sizeof(buffer1)); if (n 0) printf(%s is greater than %s.\n, buffer1, buffer2); else if (n 0) printf(%s is less than %s.\n, buffer1, buffer2); else printf(%s is the same as %s.\n, buffer1, buffer2); return 0; }完本专栏C语言持续更新中欢迎关注