memmove、memcpy和memy三个函数都是内存的拷贝,从一个缓冲区拷贝到另一个缓冲区。
memmove(voiddest,voidsrc,intcount)
memcpy(voiddest,voidsrc,intcount)
memy(voiddest,voidsrc,intch,intcount)
表头文件:#include
定义函数:voidmemcpy(voiddest,constvoidsrc,size_tn)
函数说明:memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束''/0''而结束
返回值:返回指向dest的指针
表头文件:#include
定义函数:voidmemy(voiddest,constvoidsrc,intc,size_tn);
函数说明:memy()用来拷贝src所指的内存内容前n个字节到dest所指的地址上。与memcpy()不同的是,memy()如果在src中遇到某个特定值(intc)立即停止复制。
返回值:返回指向dest中值为c的下一个字节指针。返回值为0表示在src所指内存前n个字节中没有值为c的字节。
表头文件:#include
定义函数:voidmemmove(voiddest,constvoidsrc,size_tn);
函数说明:memmove()是从一个缓冲区移动到另一个缓冲区中。
返回值:返回指向dest指针。
当dest<=src-count或dest>=src+count时,以上三个函数均不会产生覆盖问题,即源数据不会被更改。
若不在以上范围内,则源数据会被更改。
如:
chara[]={''a'',''b''};
charb[]={''c'',''d'',''e'',''f'',''g'',''h''};
memmove(a,b,sizeof(b));
或是直接charp=b+2;memmove(p,b,sizeof(b));
输出数据会发现b中数据输出已被更改。
发现即使a数组指向的空间不够存储数据,也能够移动成功。
原因|dest-src|
如果在使用这些函数时,分配给足够的空间,然后再使用就不会出现覆盖问题。也就是说如果外部分配给的空间不足以存储要拷贝的数据时,就有可能出现源数据被覆盖更改的问题。
#include
#include
#include
voidmain(void)
{
inti=0;
chara[9]={''a'',''b'',''c'',''d'',''e'',''f'',''g'',''h'',''/0''};
charp[2]={''q'',''w''};//或charp=a+2;
memmove(p,a,sizeof(a));
puts(a);
printf("_____________________________________________/n");
puts(p);
printf("_____________________________________________/n");
for(i=0;i<10;i++)
printf("%c%d/n",(a+i),a+i);
printf("_____________________________________________/n");
for(i=0;i<8;i++)
printf("%c%d/n",(p+i),p+i);
}
观察输出结果。
把memmove(p,a,sizeof(a));改为memcpy(p,a,sizeof(a));或memy(p,a,''e'',sizeof(a));再观察输出结果。
可以看出在目的存储空间不足时,便会出现源数据被覆盖改变的问题。
如果目的存储空间分配足够的空间,则便不会出现覆盖问题。
memcpy()、memmove()、memset()的实现
voidmemcpy(voidpvTo,constvoidpvFrom,size_tsize)
与strcpy相比,memcpy并不是遇到''/0''就结束,而是一定会拷贝完n个字节。
viewplaincopytoclipboardprint?
voidmemcpy(voidpvTo,constvoidpvFrom,size_tsize)
{
assert((pvTo!=NULL)&&(pvFrom!=NULL));//使用断言
bytepbTo=(byte)pvTo;//防止改变pvTo的地址
bytepbFrom=(byte)pvFrom;//防止改变pvFrom的地址
while(size-->0)
pbTo++=pbFrom++;
returnpvTo;
}
voidmemcpy(voidpvTo,constvoidpvFrom,size_tsize)
{
assert((pvTo!=NULL)&&(pvFrom!=NULL));//使用断言
bytepbTo=(byte)pvTo;//防止改变pvTo的地址
bytepbFrom=(byte)pvFrom;//防止改变pvFrom的地址
while(size-->0)
pbTo++=pbFrom++;
returnpvTo;
}
memmove()功能将指针src指向的前n个字节拷贝到dest指向的前n个内存区域中
可能出现dest和scr内存重叠的情况,都进行了很好的处理,这也是和mencpy()的区别之处
viewplaincopytoclipboardprint?
vordmemmove(voiddest,constvoidsrc,size_tcount)
{
voidret=dest;
if(dest<=src||dest>=src+count)
{
while(count--)
dest++=src++
}
else
{
dest+=count-1;
src+=count-1;
while(count--)
dest--=src--
}
returnret;
}
vordmemmove(voiddest,constvoidsrc,size_tcount)
{
voidret=dest;
if(dest<=src||dest>=src+count)
{
while(count--)
dest++=src++
}
else
{
dest+=count-1;
src+=count-1;
while(count--)
dest--=src--
}
returnret;
}
voidmemset(voids,intc,intn)
用c填充由指针s指向的内存区域的前n个字节.返回指向该内存区域的指针s.s并不一定是指向字符的指针,
以是指向任何类型的指针,甚至可以是指向结构的指针.
viewplaincopytoclipboardprint?
voidmemset(voidbuffer,intc,intcount)
{
charpvTo=(char)buffer;
assert(buffer!=NULL);
while(count-->0)
pvTo++=(char)c;
returnbuffer;
}
|
|