strcpy、strncpy、memcpy和memmove的区别

// Strncpy.cpp : 定义控制台应用程序的入口点。
/*
strcpy是一种C语言的标准库函数,strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*; 
strncpy函数用于将指定长度的字符串复制到字符数组中,并返回被复制后的dest, 是 C语言的库函数之一;
memcpy指的是C和C++使用的内存拷贝函数,函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中;
memmove用于拷贝字节,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。

strcpy和memcpy主要有以下3方面的区别。 
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。 
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。 
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

memcpy和memmove的区别:
  当内存发生局部重叠时,memmove保证拷贝结果的正确,memcpy不保证拷贝结果的正确。

*/

#include "stdafx.h"
#include <assert.h>
#include <iostream>
using namespace std;
char* my_strcpy(char *dest, const char *source);
char* my_strncpy(char *dest, const char *source, int n);
void* my_memcpy(void *dest, const void *source, int n);
void* me_memmove(void *dest, const void *source, int n);

//strcpy把含有'\0'结束符的字符串复制到目标空间
char* my_strcpy(char *dest, const char *source)  //只能拷贝字符数组
{
    if (dest == NULL || source == NULL)
    {
        return NULL;
    }
    char *tempDest =  dest;

    while ((*tempDest++ = *source++) != '\0');  //先赋值在判断(使用tempDest判断)
    return dest;
}

//strncpy函数用于将指定长度的字符串复制到字符数组中  若n小于源字符串长度,不会讲'\0'结束符复制到目标空间
char* my_strncpy(char *dest, const char *source, int n)//只能拷贝字符数组
{
    if (dest == NULL || source == NULL || n <= 0)
    {
        return NULL;
    }

    char *tempDest =  dest;
    //n--必须放在左边;&&为双目运算符若左边为假则不执行右边
    while(n-- && (*tempDest++ = *source++) != '\0'); 

    *tempDest = '\0';
    return dest;
}

//从源内存地址的起始位置,开始拷贝若干个字符(包含空字符)到目标地址
//memcpy不支持内存重叠
void *my_memcpy(void *dest, const void *source, int n)//可以拷贝任意数据对象
{
   if (dest == NULL || source == NULL || n <= 0)
   {
       return NULL;
   }
   
   char *pdest = (char *) dest;
   const char *psrc = (const char *) source;
   
   //判断内存重叠
   bool flag1 = (pdest >= psrc && pdest < psrc + n); 
   bool flag2 = (pdest <= psrc  && pdest + n > psrc );
   if (flag1 || flag2)
   {
       return NULL;
   }
   while(n--)
   {
       *pdest++ = *psrc++; 
   }
   return dest;
}

//支持内存重叠
void* me_memmove(void *dest, const void *source, int n)
{
    int i = 0;
    if (dest == NULL || source == NULL || n <= 0)
    {
        return NULL;
    }
    char * pdest =  (char *)dest;
    const char *psrc = (const char *) source;
    if (pdest < psrc)  //从低地址开始赋值(正序拷贝)
    {
        for (i = 0 ; i < n ; i++)
        {
            *pdest++ = *psrc++; 
        }
    }
    else //从高地址开始赋值(逆序拷贝)
    {
        for (i = n - 1; i >= 0; i--)
        {
            *(pdest + i) = *(psrc + i);
        }
    }
    return dest;
}

int _tmain(int argc, _TCHAR* argv[])
{
    char a[10]= {0x00};
    char b[10] = "abcd";
    //my_strcpy (a, b);
    //my_strncpy(a, b,3);
    //my_memcpy(a,b,3);
    //my_memcpy(b,b,6);
   // cout <<b<< endl; 
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/dingou/p/11312680.html