C/C++标准库函数的实现

需要的头文件:#include <string.h>

原型:

extern void* memcpy(void *dest, const void *src, size_t n);
//If copying takes place between objects that overlap, the behavior is undefined

功能:由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。

注意:

1.source和destin所指的内存区域可以重叠,但是如果source和destin所指的内存区域重叠,那么这个函数并不能够确保source所在重叠区域在拷贝之前被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向destin的指针。
2.strcpy和memcpy主要有以下3方面的区别。
2.1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2.2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
2.3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
注意:source和destin都不一定是数组,任意的可读写的空间均可。

4.标准库函数提供了地址重叠时的内存拷贝函数:memmove()因为memmove()函数把源字符串拷贝到临时buf里,然后再从临时buf里写到目的地址,增加了一次不必要的开销,但是可以解决内存重叠拷贝问题。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void *memcpy(void *dst,const void *src,size_t size);

int mian(int argc,char *argv[])
{
   char buf[100]="abcdefgh";
   Memcpy(buf+2,buf,5);//memcpy(buf+2,buf,5);
   printf("%s\n",buf+2);
}
//如果函数的参数可以是任意类型指针,那么应声明其参数为void *
void *Memcpy(void *dst,const void *src, size_t size)
{
   char *psrc;
   char *pdst;
   if(dst == NULL|| src == NULL) return NULL;
   if((src<dst)&&(char*)src+size>(char*)dst)//src和dst内存重叠,则自后向前拷贝
   {
       psrc = (char*)src+size-1;
       pdst = (char*)dst+size-;
       while(size--)
       {
          *pdst-- = *psrc--;
        }
    }
    else
    {
        psrc = (char*)src;
        pdst = (char*)dst;
        while(size--)
        {
           *pdst++ = *psrc++;
        }
     }
     return dst;
}

PS:size_t 类型定义在cstddef.h头文件中,该文件是C标准库的头文件stddef.h的C++版。它是一个与机器相关的unsigned类型,其大小足以保证存储内存中对象的大小。

在C++中,size_t的引入增强了程序在不同平台上的可移植性。size_t是针对系统定制的一种数据类型,一般是整型,因为C/C++标准只定义最低的位数,而不是必需的固定位数。而且在内存里,对数的高位对齐存储还是低位对齐存储各系统都不一样。当然,有些是编译器或系统已经给定义好的。经测试发现,在32位系统中size_t是4字节的,而在64位系统中,size_t是8字节的,这样利用该类型可以增强程序的可移植性。

关于void* :如果函数的参数可以是任意类型指针,那么声明其参数为void*;

典型的如内存操作函数memcpy和memset的函数原型分别为:

void * memcpy(void *dest, const void *src, size_t size);
void * memset ( void * buffer, int c, size_t size );
这样任何类型的指针都可以传入memcpy和memset中,真实体现了内存操作函数的意义,yinwei


转载于:https://my.oschina.net/u/347414/blog/168215

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值