C/C++知识点:C/C++的mem函数和strcopy函数的区别和应用
小职 2017-11-21 来源 :网络 阅读 851 评论 0

摘要:本篇C/C++知识点教程将为大家讲解C/C++语言编程的知识点,看完这篇文章会让你对C/C++语言编程的知识点有更加清晰的理解和运用。

本篇C/C++知识点教程将为大家讲解C/C++语言编程的知识点,看完这篇文章会让你对C/C++语言编程的知识点有更加清晰的理解和运用。

 

mem系列函数是面试的时候常考的知识点,我们需要熟练掌握这三个函数的原理和代码实现,要能准确无误的写出代码。

memcpy、memset和memset三个函数在使用过程中,均需包含以下头文件:

//在C中#include <string.h>//在C++中#include <cstring>

memcpy

memcpy函数是C/C++中的内存拷贝函数,它的功能是从源src所指的内存地址的起始位置开始,拷贝n个字节到目标dst所指的内存地址的起始位置中。

研究函数功能最好的办法就是研究其源代码,这里在网上找了一份,如下:

void * __cdecl memcpy ( void * dst,const void * src,size_t count){

    void * ret = dst;

    while (count--)

    {

        // 注意, memcpy函数没有处理dst和src区域是否重叠的问题

        *(char *)dst = *(char *)src;

        dst = (char *)dst + 1;

        src = (char *)src + 1;

    }

    return(ret);

}

源代码比较简单,定义一个计数,然后从头到尾一次将src指向的值拷贝给dst,库函数中的memcpy不能处理dst和src中存在重叠部分这种情况。

那么处理重叠部分的话,我们可以采用从后往前依次拷贝的方法,下面给出我修改过的函数代码:

void * __cdecl memcpy ( void * dst,const void * src,size_t count){

char *pDst = static_cast<char *> dst;

const char *pSrc = static_cast<const char *> src;

    //检查参数

    if(pDst==NULL || pSrc== NULL || count <=0){

     return NULL;

   }

    //判断有是否存在重叠部分

    if(pDst > pSrc && pDst < pSrc + count){

     for(size_t i=count-1; i>=0; i--)

        {

            pDest[i] = pSrc[i];

        }

    }

    else {

     for(size_t i=0; i<count; i++)

        {

            pDest[i] = pSrc[i];

        }

    }

    return pDst;

}

memset

memset一般用于对内存初始化,在这里需要注意的是,memset函数是对内存的每个字节(按字节)设置成c的值。其函数原型如下:

void memset(void *s, int c, size_t n){

const unsigned char uc = c;//将int转换成char,截去c的高24位,留下低8位

unsigned char *su;

for (su = s; 0 < n; ++su, --n)

*su = uc;

return s;

}

注意,这里有一个坑,memset一般用于将内存清零,你要是想将这段内存初始化为1而写下下面的代码:

int num[10];memset(num,1,sizeof(int)*10);

这里并不会如你所愿,num的每一个数都被初始化为16843009,原因就是上述提到的会截去c的高24位。

使用memset初始化比用for循环初始化要快很多,所以在初始化基本类型数据,结构体等的时候尽量选择memset,memset可以方便的清空一个结构类型的变量或数组。

memmove

它与memcpy的功能相似,都是将src所指的n个字节复制到dst所指的内存地址的起始位置,不同的是它处理了src和dst有重叠的情况。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。(与上述修改过得memcpy基本一致)

所以基本原则就是,如果你能确保两段内存没有重叠的部分,就使用memcpy来进行拷贝;如果你不能确定,为了保证复制的正确性,必须用memmove。
其实现代码如下:

void* memmove(void* dest, void* src, size_t count)

{

void* ret = dest;

if (dest <= src || dest >= (src + count))

{

//Non-Overlapping Buffers

//copy from lower addresses to higher addresses

while (count --)

*dest++ = *src++;

}

else

{

//Overlapping Buffers

//copy from higher addresses to lower addresses

dest += count - 1;

src += count - 1;

while (count--)

*dest-- = *src--;

}

return ret;

}

strcpy

strcpy是C语言的标准库函数,使用strcpy需要包含以下头文件:

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

其函数功能是把从src地址开始且含有NULL结束符的字符串复制到dst开始的地址空间,返回指向dst的指针。其函数代码如下:

char* strcpy(char* dst , char* src){

if(dst==NULL||src==NULL) return NULL;// --1

if(dst==src) return dst; //--2

char* address = dst; //--3

while((*dst++ = *src++)!='\0') //--4

return address;  //--5

}

图中标出来的都是考点,下面一一说明:

· 1、需要判断参数的正确性,这里也可以抛出一个异常

· 2、如果指向了同一块内存,不用复制直接返回即可

· 3、这里需要保存原始的dst指针,用作返回值

· 4、这里有一个技巧,如果写成以下两种,面试的时候会大大扣分!

//第一种while(*dst++ = *src++)  //直接越界访问,没有检查指针的有效性//第二种while(*src!='\0'){*dst++ = *src++;}//考虑了src的边界问题,没有在dst的后面加'\0',会导致dst的长度未知引起错误

· 5、函数返回dst的原始值是为了能够支持链式表达式,增加了函数的附加性。

上述第5点可以用如下测试代码来说明:

int length = strlen(strcpy(strA,strB));//如果不支持链式表达式,这里会报错。

那么有时候也会问为什么不返回src的原始值,错误原因有以下三点:

· 源字符串本来就已知,返回没有什么意义

· 不能支持形如char * strA = strcpy(new char[10],strB) 这样的表达式

· 为了保护源字符串,使用const限定了src所指的内容,把const char作为char的返回值,类型不符,编译器会报错。

strcpy和memcpy的不同点

这个也是常见的考点,主要分为以下三点不同:

· 复制内容不同:strcpy只能复制字符串,而memcpy可以复制任何内容,例如字符数组,整型,结构体等

· 复制的方法不同:strcpy不需要指定长度,它遇到字符串结束符’\0’才结束,所以容易溢出。memcpy则需要传入第三个参数来指定长度

· 用途不同:通常在复制字符串的时候用strcpy,而需要复制其他数据类型的时候则一般用memcpy。

 

以上,关于C/C++知识点的全部内容讲解完毕啦,欢迎大家继续关注!更多关于C/C++知识点的干货请关注职坐标C语言频道!

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程