1. memcpy使用和模拟实现
void * memcpy ( void * destination, const void * source, size_t num );
• 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
• 这个函数在遇到 ‘\0’ 的时候并不会停下来。
• 如果source和destination有任何的重叠,复制的结果都是未定义的。
(对于重叠的内存,交给第二个函数memmove来处理。)
eg:
#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;
}
memcpy函数的模拟实现:
void * my_memcpy ( void * dst, const void * src, size_t count)
{
void * ret = dst;
assert(dst);
assert(src);
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
-
首先将目标内存区域的起始地址赋值给指针变量ret,以备最后返回。
-
然后通过assert函数来检查目标内存区域和源内存区域的地址是否有效,如果地址无效,则程序会终止。
-
进入while循环,每次循环会将源内存区域的一个字节数据复制到目标内存区域中。
-
在循环中,将源内存区域和目标内存区域的指针分别转换为(char *)类型,以便逐字节复制数据。
-
每次循环完成后,将目标内存区域和源内存区域的指针分别后移一个字节,以便进行下一次数据复制。
-
当count减为0时,表示所有数据已经复制完成,函数返回最初的目标内存区域起始地址ret。
2. memmove使用和模拟实现
void * memmove ( void * destination, const void * source, size_t num );
• 和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。
eg:
#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 ", arr2[i]);
}
return 0;
}
那结果自然就是:1 2 1 2 3 4 5 8 9 10
memmove的模拟实现:
这个就有点小复杂咯
void * my_memmove ( void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count)) {
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else {
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}
- 首先将目标内存区域的起始地址赋值给指针变量ret,以备最后返回。
- 接着通过判断源内存区域和目标内存区域的相对位置,来确定移动方式:
如果目标内存区域的起始地址小于等于源内存区域的起始地址,或者目标内存区域的结束地址大于等于源内存区域的结束地址,则采用正向移动方式。
否则,采用反向移动方式。 - 对于正向移动方式,通过while循环逐个字节地将源内存区域的数据复制到目标内存区域中,并且每次循环后将指针向后移动一个字节。
- 对于反向移动方式,先将目标内存区域和源内存区域的指针移动到最后一个字节的位置,然后通过while循环逐个字节地将源内存区域的数据复制到目标内存区域中,并且每次循环后将指针向前移动一个字节。
- 当所有数据移动完成后,函数返回最初的目标内存区域起始地址ret。
3. memset函数的使用
void * memset ( void * ptr, int value, size_t num );
memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。
eg:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
结果:
xxxxxxworld
4. memcmp函数的使用
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
• 比较从ptr1和ptr2指针指向的位置开始,向后的num个字节
比较两个内存块。它比较ptr1和ptr2指向的内存区域的前n个字节。函数返回一个整数,如果ptr1的前n个字节小于、等于或大于ptr2的前n个字节,则分别返回小于零、等于零或大于零。
#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;
}
‘DWgaOtP12df0’ is greater than ‘DWGAOTP12DF0’.
那么本期文章就到这里,感谢大家的观看,我们下期再见咯
下期预告
······结构体