一、内存操作函数
内存操作函数在库<string.h>中,可以通过内存函数设置参数,本文主要介绍了内存函数的使用方法以及实现原理。
二、使用及仿写
1.memcpy
cplusplus网站可以看到memcpy的定义如下:
将num个字节从src拷贝到des中,返回void * 类型的指针,我需要知道des的起始地址
实现这个函数思路:一个一个字节拷贝,循环次数为num,将des的起始地址记录
实现代码如下:
void* my_memcpy(void* des, const void* src, size_t num)
{
//断言,增加代码的健壮性
assert(des);
assert(src);
//返回void * 类型的指针,我需要des的首地址
void * ret = des;
while (num--)
{
*(char*) des = *(char*)src; //注意这里 指针先转换为char类型,取src指向的内容,每次更改一个字节
// (char*)src++; void * 类型的指针不能直接++,需要强制转换
src = (char*)src + 1;
des = (char*)des + 1;
}
return ret;
}
2.memmove
memmove的官方定义如下:
将src指向的地址拷贝到des的地址中,拷贝num个字节。这个函数允许内存重叠
为了避免溢出,src和des指向的地址起码是num个字节的大小
实现思路:
使用char类型的单个字节进行拷贝
具体地,要考虑src和des的位置 str1:1 2 3 4 5 6 7 8 9
如果src在des的前面,即将str2中的 1 2 3 4 5 拷贝到 3 4 5 6 7 的位置,变成 1 2 1 2 3 4 5 8 9
如果顺着数组的顺序遍历,将 1 先拷到 3 的位置,则会覆盖掉这个数字 所以需要从后向前遍历
*(src+ num) = *(des +num)
循环赋值,赋num次
如果src在num的后面,即将 3 4 5 6 7 拷贝到 1 2 3 4 5的位置,变成 3 4 5 6 7 6 7 8 9
顺着数组的顺序遍历,和memcpy相同
* des = *src 循环num次
实现代码如下:
void* my_memmove(void* des, void* src, size_t num)
{
assert(des);
assert(src);
void* ret = des;
if (src > des)
{
while (num--)
{
*((char*)des + num) = *((char*)src + num); //注意这里,先强制类型转换,然后+num之后再取地址赋值
}
}
if (src < des)
{
while (num--)
{
*(char*)des = *(char*)src;
src = (char*)src + 1;
des = (char*)des + 1;
}
}
return ret;
}
3.memcmp
memcmp的官方定义如下,比较ptr1和ptr2中的num个字节,返回值如下:
使用方法:
int main()
{
int arr1[]={1,2,3,0,5};
int arr2[]={1,2,3,4,0};
int ret = memcmp(arr1,arr2,12) //比较arr1和arr2中13个字节
printf("%d",ret);
return 0;
}
//arr1中的数据存放如下(假设小端存储),内存从低到高
//01 00 00 00 02 00 00 00 03 00 00 00 00 00 00 00 05 00 00 00
//arr2中的数据存放如下:
//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
//比较前13个字节 04>00 ,return >0 的数
4.memset
memset官方定义如下:设置ptr指向的起始地址的值为value,设置num个字节,返回ptr的起始地址
使用方法如下:
int main()
{
int arr[] = {1,2,3,4,5};
memset(arr,1,9) //设置arr的9个字节为1
//打印
return 0;
}
总结
本文主要介绍了内存函数(memcpy,memmove,memset,memcmp)的使用方法以及实现原理,技术有限,若有错误请指正。