今天我们讲了解三个有关内存的函数:
1.memcpy
2.memmove
3.memcmp
1.memcpy
1.1函数原型
memcpy函数是C语言标准库中的一个内存复制函数,用于将指定长度的数据从源地址复制到目标地址。其函数原型如下:
void memcpy(void dest, const void src, size_t n);
这里的 dest 是目标内存地址,src是源内存地址,n 是要复制的字节数。memcpy函数不会检查目标地址是否有足够的空间,因此在使用时要确保目标地址有足够的空间来存储复制的数据。
memcpy函数不像 strcpy 函数一样专门用于字符串复制,它是通用的内存复制函数,可以用于任意类型的数据复制。它是按字节进行复制的,因此在对非字符类型的数据进行复制时更为常见。
注意:
目标地址必须具有足够的空间来容纳源地址的数据。
memcpy 函数可以用于复制任意类型的数据,而不仅仅是字符串。
它是按字节复制的,因此可以用于任何数据类型的复制,但需要注意字节顺序和内存对齐问题。
1.2函数的模拟实现
#include <stdio.h>
// 自定义的简单实现memcpy函数
void* my_memcpy(void* dest, void* src, size_t n) {
// 将void指针转换为char指针
char* cdest = (char*)dest; // 目标内存地址的char指针
char* csrc = (char*)src; // 源内存地址的char指针
// 逐字节复制数据
for (size_t i = 0; i < n; i++) {
cdest[i] = csrc[i]; // 复制数据
}
return dest; // 返回目标内存地址的指针
}
int main() {
char src[] = "Hello, this is a test."; // 源字符串
char dest[50]; // 目标字符串
// 调用自定义的my_memcpy函数进行复制
my_memcpy(dest, src, sizeof(src));
// 输出复制后的结果
printf("Copied string: %s\n", dest);
return 0;
}
2.memmove
2.1函数原型
memmove 函数与 memcpy 函数非常相似,它们都用于在内存中移动数据块。然而,memmove 函数与 memcpy 函数在处理重叠内存区域的情况时有所不同。当源内存区域与目标内存区域重叠时,memcpy 可能会导致不可预测的结果。
而 memmove 函数则能够正确处理这种情况,保证数据被正确复制。
void *memmove(void *dest, const void *src, size_t n);
memmove 函数将源地址 src 处的数据复制到目标地址 dest 处,复制的字节数为 n。与 memcpy 不同的是,memmove 函数可以处理重叠的内存区域,它会根据重叠的情况选择合适的方式进行复制,保证数据不会被破坏。
2.2模拟实现
#include <stdio.h>
#include <string.h>
// 模拟实现memmove函数
void *my_memmove(void *dest, const void *src, size_t n) {
// 如果目标和源指针相同,直接返回
if (dest == src) {
return dest;
}
// 如果目标地址小于源地址,从前往后复制
if (dest < src) {
// 将指针转换为char类型,以便按字节操作
char *d = (char *)dest;
const char *s = (const char *)src;
// 循环复制n个字节
while (n--) {
*d++ = *s++;
}
} else {
// 如果目标地址大于源地址,从后往前复制
// 将指针转换为char类型,并向后移动n-1个字节
char *d = (char *)dest + n - 1;
const char *s = (const char *)src + n - 1;
// 循环复制n个字节
while (n--) {
*d-- = *s--;
}
}
// 返回目标指针
return dest;
}
int main() {
char str[] = "Hello, World!";
printf("Original string: %s\n", str);
// 使用my_memmove函数将字符串前6个字符移动到字符串的末尾
my_memmove(str, str + 7, 6);
my_memmove(str + 6, "!", 2);
printf("Modified string: %s\n", str);
return 0;
}
3.memcmp
3.1函数模型
memcmp 函数用于比较两个内存区域的内容是否相等。它按字节比较两个内存区域的前 n 个字节,可以用于任意类型的数据比较,而不仅仅是字符串。
`int memcmp(const void *s1, const void *s2, size_t n);
memcmp 函数将内存区域 s1 和 s2 进行逐字节比较,比较的字节数由参数 n 指定。如果两个内存区域相等,函数返回值为 0;如果 s1 大于 s2,返回值大于 0;如果 s1 小于 s2,返回值小于 0。
3.2模拟实现
#include <stdio.h>
#include <string.h>
// 模拟实现memcmp函数
int my_memcmp(const void *s1, const void *s2, size_t n) {
// 将指针转换为char类型,以便按字节操作
const char *p1 = (const char *)s1;
const char *p2 = (const char *)s2;
// 循环比较n个字节
while (n--) {
// 如果出现不同的字节,返回差值
if (*p1 != *p2) {
return *p1 - *p2;
}
// 否则,指针后移
p1++;
p2++;
}
// 如果没有不同的字节,返回0
return 0;
}
int main() {
char str1[] = "Hello, World!";
char str2[] = "Hello, C!";
int ret;
// 使用my_memcmp函数比较两个字符串
ret = my_memcmp(str1, str2, strlen(str1));
if (ret > 0) {
printf("str1 大于 str2\n");
} else if (ret < 0) {
printf("str1 小于 str2\n");
} else {
printf("str1 等于 str2\n");
}
return 0;
}