内存函数
目录
前言
内存函数的作用是什么,为什么我们需要内存函数
首先大家都知道字符串操作函数例如:strstr,strlen,strcpy,字符串操作函数包含在头文件string.h中,而内存函数也包含在头文件string.h中,那为什么我们有了strncpy还需要memcpy呢,内存函数是以字节为单位改变内存里存储的值,直接访问地址,不会要求参数数据类型,比strncpy范围更广。
1.memcpy
memcpy的函数与strcpy作用相似但范围更广,strncpy是将一个字符串拷贝到另一个字符串,而memcpy是将一个数组拷贝到一个相同类型的数组里去。
void * memcpy ( void * destination, const void * source, size_t num );
第一个参数void* destination指的是目标数组即最终拷贝到的数组的首指针
第二个参数const void* source指的是被拷贝数组的首指针
第三个参数size_t num指的是将从source开始的num个字节拷贝给destination,一个字节一个字节拷贝
大家可以比较一下memcpy和strncpy
void * memcpy ( void * destination, const void * source, size_t num );
char * strncpy ( char * destination, const char * source, size_t num );
strncpy限制的数据类型为char,而memcpy为void不限制,所以memcpy可以处理更多类型的数据
int main()
{
int dest[] = {1,2,3,4,5,6,7};
int src[] = { 4,5,6,7 };
int i;
memcpy(dest, src, 16);//内存函数这里的size是以字节作为单位
for (i = 0; i < (sizeof(dest)/4); i++)
{
printf("%d ", dest[i]);
}
return 0;
}
这段代码的输出是这样的
这里用的整型数组,我想让他传四个元素给dest,所以字节数为16(64位编译为32)
int main()
{
char str[] = "abcdef";
char str1[] = "hijk";
memcpy(str, str1, 5);//如果要复制\0就是5,不复制就是4
printf("%s", str);
}
这里用memcpy的结果和strcpy的结果是一样的
1.1memcpy的模拟实现
因为char型占一个字节,所以只要将传入的指针类型强转成char*,指针+1才会只跳过一个字节否则如果是指向int的指针,+1会直接跳过四个字节。
void my_memcpy(void* a, void* b,size_t n)
{
int i;
for (i = 0; i < n; i++)
{
*(char*)a = *(char*)b;//强转成char*一个字节一个字节拷贝
a = (char*)a+1;
b = (char*)b+1;
}
}
2.memmove
void * memmove ( void * destination, const void * source, size_t num )
这三个参数和memcpy一模一样
第一个参数void* destination指的是目标数组即最终拷贝到的数组的首指针
第二个参数const void* source指的是被拷贝数组的首指针
第三个参数size_t num指的是将从source开始的num个字节拷贝给destination,一个字节一个字节拷贝
memmove是专门用来处理memcpy所处理不了的原空间和目标空间重叠的问题
如果我想要将1,2,3放在3,4,5的位置上,最终数组变成
可是如果是memcpy的处理,当我们将1赋给3所在地址时那3就被覆盖,当你想将3赋给5所在的地址时就会发现3已经被1覆盖了,实际上你是将1赋给了5所在的位置。
为什么会导致这样的结果,就是因为原空间和目标空间重叠的问题。
memmove就是专门处理这样的问题
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
memmove(arr+2, arr, 12);
}
2.1memcpy模拟实现
要模拟实现memcpy那么我们就要考虑覆盖的内容和目标数组和被拷贝数组的位置。
如果src<dest那么就要从后往前赋值,例如这里先将3存放到5所在的地址,再将2存放到4所在的地址,最后再将1赋给3
如果src>dest那么就要从前往后赋值。
void my_memmove(void* dest, void* src, size_t num)//memmove模拟实现
{
if (src > dest)
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
}
如有不对的地方还请指正。