【C语言】深入理解C语言内存操作函数:memcpy、memmove、memset与memcmp
目录
- 1. memcpy函数的使用与模拟实现
- 1.1 函数介绍
- 1.2 使用示例
- 1.3 模拟实现
- 2. memmove函数的使用与模拟实现
- 2.1 函数介绍
- 2.2 使用示例
- 2.3 模拟实现
- 3. memset函数的使用
- 3.1 函数介绍
- 3.2 使用示例
- 4. memcmp函数的使用
- 4.1 函数介绍
- 4.3 使用示例
🔥个人主页:@月夜的风吹雨
🎥作者简介: C++研发方向学习者
📖个人专栏:《C语言》
🌄人生格言: 任何一个伟大的思想,都有一个微不足道的开始。
前言:在C语言编程中,对内存的直接操作是非常常见且重要的任务。为了高效、安全地处理内存数据,C标准库提供了一系列内存操作函数。本文将详细介绍memcpy、memmove、memset和memcmp这四个函数的使用方法、区别以及模拟实现,帮助大家更好地理解并掌握这些基础但强大的工具。
1. memcpy函数的使用与模拟实现
1.1 函数介绍
memcpy
函数的原型如下:
该函数用于将source
指向的内存地址开始的num
个字节数据复制到destination
指向的内存地址。
注意:
memcpy
不会因为遇到'\0'
而停止复制,且如果源地址与目标地址存在重叠,其行为是未定义的。
1.2 使用示例
#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); // 复制前20个字节(即5个int)for (int i = 0; i < 10; i++) {printf("%d ", arr2[i]);}return 0;
}
输出结果:
1 2 3 4 5 0 0 0 0 0
1.3 模拟实现
void* my_memcpy(void* dst, const void* src, size_t count) {void* ret = dst;assert(dst && src); // 确保指针有效while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}return ret;
}
在while循环中为何不能使用
*(char*)dst++ = *(char*)src++
? 这是因为对dest的 (char*)强制类型转换只是临时性的,执行后dest仍会恢复为void类型指针,而void指针不支持自增运算。
🔍注意:该实现是按字节从前向后复制,适用于非重叠内存区域。
2. memmove函数的使用与模拟实现
2.1 函数介绍
memmove
函数的原型与memcpy
相同:
与memcpy
不同的是,memmove
可以处理内存重叠的情况。它是更安全的复制函数。
2.2 使用示例
#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); // 将前5个元素复制到第3个位置开始for (int i = 0; i < 10; i++) {printf("%d ", arr1[i]);}return 0;
}
输出结果:
1 2 1 2 3 4 5 8 9 10
2.3 模拟实现
void* my_memmove(void* dest, const void* src, size_t num) {assert(dest && src);void* ret = dest;if ((char*)dest <= (char*)src || (char*)dest >= (char*)src + num) {//往前交换,先交换src前面的字节while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else {//先定位交换的位置dest = (char*)dest + num - 1;src = (char*)src + num - 1;//往后交换,先交换src后面的字节while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest - 1;src = (char*)src - 1;}}return ret;
}
🛠️ 提示: memmove
通过判断内存是否重叠,选择不同的复制方向,确保数据正确性。
3. memset函数的使用
3.1 函数介绍
memset
函数的原型如下:
该函数用于将ptr
指向的内存区域的前num
个字节设置为value
的值(按字节设置)。
3.2 使用示例
#include <stdio.h>
#include <string.h>int main() {char str[] = "hello world";memset(str, 'x', 6); // 将前6个字符设为'x'printf("%s", str);return 0;
}
输出结果:
xxxxxxworld
- 💡 用途: 常用于初始化数组、清空缓冲区等。
4. memcmp函数的使用
4.1 函数介绍
memcmp
函数的原型如下:
该函数用于比较ptr1
和ptr2
指向的内存区域的前num
个字节的内容。
返回值 | 含义 |
---|---|
<0 | ptr1 小于ptr2 |
0 | 内容相等 |
>0 | ptr1 大于ptr2 |
4.3 使用示例
#include <stdio.h>
#include <string.h>int main() {char buf1[] = "DWga0tP12df0";char buf2[] = "DWGA0TP12DF0";int n = memcmp(buf1, buf2, sizeof(buf1));if (n > 0) printf("'%s' > '%s'\n", buf1, buf2);else if (n < 0) printf("'%s' < '%s'\n", buf1, buf2);else printf("'%s' == '%s'\n", buf1, buf2);return 0;
}
输出结果:
'DWga0tP12df0' > 'DWGA0TP12DF0'
- 📌 注意: 比较是按字节进行的,不考虑字符串结束符。
理解并熟练使用这些内存操作函数,是每一位C语言程序员的基本功。它们不仅在底层开发中广泛应用,也在高性能计算、嵌入式系统等领域中发挥着重要作用。
📚更多C语言教程,欢迎关注我的CSDN博客!
👉月夜的风吹雨 《C语言》