新普京网站-澳门新普京 > 前端 > 的mem函数和strcopy函数的区别和应用,c语言之字符串处理

的mem函数和strcopy函数的区别和应用,c语言之字符串处理

2019/12/29 22:05

澳门新普京 ,mem体系函数是面试的时候常考的知识点,我们须求熟悉通晓那三个函数的规律和代码完成,要能精确科学的写出代码。

1.字串拷贝库函数strcpy

  函数介绍:

  原型注解:extern char *strcpy(char *dest,const char *src);

  头文件:string.h

新普京网站 ,  功用:把从src地址开头且含有NULL截止符的字符串赋值到以dest领头的地方空间

  表达:src和dest所指内部存款和储蓄器区域不能重叠且dest必得有充分的上空来兼容src的字符串。

  重回指向dest的指针

  规范达成:

1   char *strcpy(char *strDestination, const char *strSource)  2   {  3   4         assert(strDestination!=NULL && strSource!=NULL)  5         char *strD=strDestination;  6        while ((*strDestination++=*strSource++)!='');  7         return strD;  8   }            

  常见难点:

  [1]
  (A卡塔尔国不反省指针的有效性,表达答题者不讲究代码的强壮性。
  (B卡塔尔检查指针的管事时利用((!strDest)||(!strSrc))或(!(strDest&&strSrcState of Qatar卡塔尔,表明答题者对C语言中项目标隐式调换未有深入认知。在本例中char *转移为bool正是类型隐式转变,这种效果与利益纵然灵活,但越来越多的是招致出错可能率增大和掩护资金上涨。所以C++专门扩充了bool、true、false多个关键字以提供更安全的尺度表明式。
  (C卡塔尔(قطر‎检查指针的有用时选取((strDest==0State of Qatar||(strSrc==0卡塔尔(قطر‎State of Qatar,表达答题者不驾驭使用常量的低价。直接接纳字面常量(如本例中的0)会减小程序的可维护性。0即使轻巧,但顺序中可能现身众多处对指针的检查,万大器晚成现身笔误,编写翻译器不可能觉察,生成的次序内含逻辑错误,很难打消。而接受NULL代替0,假设出现拼写错误,编译器就能够检讨出来。
  [2]
  (A卡塔尔国return new string("Invalid argument(s卡塔尔国"卡塔尔(قطر‎;,表达答题者根本不晓得再次回到值的用处,况且她对内部存款和储蓄器泄漏也从未警惕心。从函数中重返函数体内分配的内存是非凡饮鸩止渴的做法,他把自由内部存款和储蓄器的无需付费抛给不知情的调用者,绝大许多意况下,调用者不会释放内存,那引致内存泄漏。
  (BState of Qatarreturn 0;,表明答题者没有调节卓殊机制。调用者有相当大可能率忘记检查重临值,调用者还恐怕不能检查再次回到值(见前边的链式表明式)。图谋让再次来到值肩负再次来到精确值和极其值的再一次效果,其结果往往是两种效应都失效。应该以抛出十一分来取代重回值,那样能够减轻调用者的肩负、使错误不会被忽略、加强程序的可维护性。
  [3]
  (A卡塔尔(قطر‎忘记保存原有的strDest值,表达答题者逻辑思谋不严峻。
  [4]
  (AState of Qatar循环写成while (*strDest++=*strSrc++);,同[1](B)。
  (B卡塔尔循环写成while (*strSrc!='') *strDest++=*strSrc++;,表明答题者对边界条件的自己商议不力。循环体结束后,strDest字符串的最后未有精确地拉长''。
  2.赶回strDest的原始值使函数能够扶助链式表明式,扩展了函数的“附加值”。相通服从的函数,假诺能成立地抓牢的可用性,自然就一发优良。
  链式表达式的样式如:
  int iLength=strlen(strcpy(strA,strB));
  又如:
  char * strA=strcpy(new char[10],strB);
  重临strSrc的原始值是指鹿为马的。其生机勃勃,源字符串肯定是已知的,再次来到它一点意义都没有。其二,不能够支撑形如第二例的表明式。其三,为了掩护源字符串,形参用const节制strSrc所指的剧情,把const char *作为char *重临,类型不符,编译报错。

2.内存拷贝库函数memcpy

  函数介绍:

  函数原型:
  void *memcpy(void *dest, const void *src, size_t n);
  功能:
  从源src所指的内存地址的起第二位置上马拷贝n个字节到目的dest所指的内部存款和储蓄器地址的初叶地方中
  所需头文件:
  #include <memory.h>
  返回值:
  函数再次来到dest的值。
  说明:
  1.source和destin所指内部存款和储蓄器区域不能够重叠,函数重返指向destin的指针。
  2.strcpy和memcpy首要有以下3上边的界别。
  2.1、复制的始末莫衷一是。strcpy只好复制字符串,而memcpy能够复制大肆内容,举个例子字符数组、整型、构造体、类等。
  2.2、复制的艺术分化。strcpy不须求钦命长度,它碰着被复制字符的串结束符""才停止,所以轻便溢出。memcpy则是依赖其第2个参数决定复制的长短。
  2.3、用项不一致。常常在复制字符串时用strcpy,而要求复制其余项目数据时则平日用memcpy
  3.只要目的数组destin本身本来就有数量,推行memcpy()后,将覆盖原有数据(最多覆盖n)。借使要加进数据,则每一回施行memcpy后,要将目的数组地址增至您要扩充数据的地址。

  标准完成:

 1 void * __cdecl memcpy (   2         void * dst,   3         const void * src,   4         size_t count   5         )   6 {   7         void * ret = dst;   8         /*   9          * copy from lower addresses to higher addresses  10          */  11         while (count--) {  12                 *(char *)dst = *(char *)src;  13                 dst = (char *)dst + 1;                src = (char *)src + 1;  14         }  15         return(ret);  16 }

3.内部存款和储蓄器移动库函数memmove

  函数介绍:

  原型:void *memmove( void* dest, const void* src, size_tcount );
  用法:#include <string.h>或#include <memory.h>
  功用:由src所指内部存款和储蓄器区域复制count个字节到dest所指内部存款和储蓄器区域。
  表达:src和dest所指内部存款和储蓄器区域能够重叠,但复制后dest内容会被退换。函数再次回到指向dest的指针。
  相关函数:memset、memcpy

  标准完结:

 1 void * __cdecl memmove (   2         void * dst,   3         const void * src,   4         size_t count   5         )   6 {   7         void * ret = dst;   8     9         if (dst <= src || (char *)dst >= ((char *)src + count)) {  10                 /*  11                  * Non-Overlapping Buffers  12                  * copy from lower addresses to higher addresses  13                  */  14                 while (count--) {  15                         *(char *)dst = *(char *)src;  16                         dst = (char *)dst + 1;  17                         src = (char *)src + 1;  18                 }  19         }  20         else {  21                 /*  22                  * Overlapping Buffers  23                  * copy from higher addresses to lower addresses  24                  */  25                 dst = (char *)dst + count - 1;  26                 src = (char *)src + count - 1;  28                 while (count--) {  29                         *(char *)dst = *(char *)src;  30                         dst = (char *)dst - 1;  31                         src = (char *)src - 1;  32                 }  33         }  34    35         return(ret);  36 }

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;
}
上一篇:信托行使详细明白,委托及其用法 下一篇:没有了