配色: 字号:
mem系列函数实现
2012-08-06 | 阅:  转:  |  分享 
  
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;

}

献花(0)
+1
(本文系小云蔡首藏)