文章目录
1.memcpy使⽤和模拟实现
c
void * memcpy ( void * destination, const void * source, size_t num );//可以拷贝许多类型的数据,所以数据地址类型是void*
功能
• 从源头指向的内存块拷贝固定字节数的数据到目标指向的内存块
• memcpy:memory copy(内存拷贝)
• 要包含头文件==<string.h>==
• 与strcpy函数不同的点:这个函数在遇到 '\0' 的时候并不会停下来,总是精确地拷贝参数传入的字节数
• 如果source和destination有任何的重叠,复制的结果都是未定义的。
参数
destination:指针,指向目标空间,拷贝的数据存放在这里
source:指针,指向源空间,要拷贝的数据从这里来
num:要拷贝的数据占据的字节数
返回值
函数运行结束后返回拷贝后的目的地内存块的起始地址
c
#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;
}
//或者
int main()
{
float arr1[]={1.2f,2.2f,3.2f,4.2f,5.5f};
float arr2[10]={0};
// memcpy(arr2,arr1,20);
memcpy(arr2,arr1,5*sizeof(float));//忘记浮点数的字节数可以这样做
return 0;
}

有个题外话:float型无法精确保存数据
memcpy函数的模拟实现:
c
void * memcpy ( void * dest, const void * src, size_t num)
{
void * ret = dest;
assert(dest);
assert(src);
while (num--)
{
*(char *)dest = *(char *)src;//转换成char*可以一个字节一个字节赋值,但是是临时转换
//如果转换为整型,只能四个字节四个字节赋值
src=(char*)src+1;//需要再重新转换成char*
dest=(char*)dest+1;
//不能写成
//*(char*)dest++=*(char*)src++;
//因为dest和src会先转换成char*,但是++操作会给dest和src++,而不是给(char*)dest和(char*)src进行++操作
}
return ret;
}
注意
void*不能进行++操作,因为void *是一个指向未知类型的指针类型,它的大小是不确定的。而++操作需要知道指针所指向的对象的大小,才能正确的进行指针运算。
如果出现下段这种代码:
c
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memcpy(arr1+2, arr1, 20);
int i = 0; for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
//输出结果却是1 2 1 2 1 2 1
分析:因为目标空间和源头空间重复,给arr[4]拷贝时arr[2]已经被拷贝为1了,所以arr[4]会被拷贝现在arr[2]的值,那怎么解决这个问题呢,可以用memmove函数(但是vs编译器的memcpy可以拷贝重叠空间,属于超额完成任务)
2.memmove使⽤和模拟实现
c
void * memmove ( void * destination, const void * source, size_t num );//和memcpy参数一样
功能
• memmove函数也是完成内存拷贝的
• memmove函数处理的源内存块和⽬标内存块是可以重叠,也可以不重叠。
• 需要包含头文件==<string.h>==
参数
destination:指针,指向目标空间,拷贝的数据存放在这里
source:指针,指向源空间,要拷贝的数据从这里来
num:要拷贝的数据占据的字节数
返回值
函数运行结束后,返回目标空间的起始地址
c
#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 ", arr1[i]);
}
return 0;
}
输出的结果: 1 2 1 2 3 4 5 8 9 10
memmove的模拟实现:

第二种方法
c
#include<stdio.h>
#include<assert.h>
void* my_memmove ( void * dest, const void * src, size_t num)
{
assert(dest&&src);
void* ret=dest;//先存起来
if(dest>src)
{
while(num--)
{
*(char*)dest=*(char*)src;
dest=(char*)dest+1;
src=(char*)src+1;
}
}
else
{
while(num--)
{
*((char*)dest+num)=*((char*)src+num);
}
}
return ret;//与memmove函数保持一致
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
第一种方法
c
#include<stdio.h>
#include<assert.h>
void * memmove ( void * dest, const void * src, size_t count)
{
assert(dest&&src);
void * ret = dst;
if (dest <= src || (char *)dest >= ((char *)src + count))
{
while (count--)
{
*(char *)dest = *(char *)src;
dest = (char *)dest + 1;
src = (char *)src + 1;
}
}
else
{
dest = (char *)dest + count - 1;
src = (char *)src + count - 1;
while (count--)
{
*(char *)dest = *(char *)src;
dest = (char *)dest - 1;
src = (char *)src - 1;
}
}
return(ret);
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
3.memset函数的使⽤和模拟实现
c
void * memset ( void * ptr, int value, size_t num );
功能
• memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。
• 需包含头文件==<string.h>==
参数
ptr:指针,指向要设置的内存空间,存放了要设置的内存空间的起始地址
value:要设置的值,函数将会把value值转换成unsigned char的数据进行设置的,也就是以字节为单位来设置内存块的
num:要设置的内存长度,单位是字节
返回值
函数运行完之后返回要设置的内存空间的起始位置
c
#include<stdio.h>
#include<string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
输出的结果: xxxxxxworld
注意
memset函数对内存单元的设置是以字节为单位的
c
int main()
{
int arr[10]={0};
memset(arr,1,40);
return 0;
}
结果如下:发现每个字节都设置为1,而不是00 00 00 01
4.memcmp函数的使⽤和模拟实现
c
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
功能
• ⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节
• 需包含头文件==<string.h>==
参数
ptr1:指针,指向一块待比较的内存块
ptr2:指针,指向另外一块待比较的内存块
num:指定的比较长度,单位是字节
返回值
示例一:
c
int main()
{
int arr1[]={1,2,3,4,5,6,7,8,9,10};
int arr2[]={1,2,3,4,8};
int r=memcmp(arr1,arr2,17);
if(r>0)
printf(">\n");
else if(r<0)
printf("<\n");
else
printf("=\n");
return 0;
}

示例二:
c
#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;
}
