• 软件:1160
  • 资讯:41601|
  • 收录网站:97880|

IT精英团

手写strcpy和memcpy代码的实现

手写strcpy和memcpy代码的实现

浏览次数:
评论次数:
编辑: 温瑜
信息来源: 51CTO博客
更新日期: 2021-06-11 01:10:31
摘要

手写strcpy和memcpy代码实现,本篇文章聊一下strcpy和memcpy的代码实现,这两个也是c和c++面试中常考的问题点。1.手写strcpy首先看一下,一份标准的strcpy的实现如下:char*strcpy(char*strDest,constchar*strSrc){assert((strDest!=NULL)&&(strSrc!=NULL));

  • 资讯详情

本文讨论了strcpy和memcpy的代码实现,这也是C和C面试中常见的问题。

1. 手写strcpy

首先,看看标准strcpy的实现,如下所示:

char *strcpy(char* strDest,const char* strSrc)

{

assert((strDest!=NULL) (strSrc!=NULL));

char * address=strDest

while((*strDest=*strSrc)!='\0');

回信地址;

}

以下是需要注意的几点:

源字符串应该使用const类型,以避免在程序中被修改;

应该在函数入口添加断言,检查源字符串指针和目标字符串指针是否为空,否则会出现意外错误;

使用while循环简单明了,尽可能使用简洁的代码;

返回值为char*,返回目标字符串指针的原始值,使函数能够支持链式表达式,增加函数的附加值。

以上几点不仅适用于strcpy,我们在编写代码的时候也应该遵循这些规则,这样才能写出高可用性和健壮性的代码。

至于上面的代码,我们可以看出它有隐患。当源字符串长度超过目标字符串时,会导致把数据写到我们无法控制的地址,风险很大,所以有strncpy。下面是strncpy的实现,如下所示:

char *strncpy(char* strDest,const char* strSrc,size_t n)

{

assert((strDest!=NULL) (strSrc!=NULL));

char * address=strDest

while (n - (*strDest=*strSrc)!='\0');

回信地址;

}

我们需要根据输入的长度来控制,但是当我们使用它时,输入的长度是目标字符串的长度减1,因为我们需要为终止符' \0 '留一个位置。

2. memcpy的实现

其实memcpy的实现可以参考strncpy的实现。例如,我们将指针类型转换为char*进行复制。这种方式是一次复制一个字节。首先最好看代码,如下:

#包含stdio.h

#include string.h

指导人们

{

int iAge

char SZName[12];

char SsSex[3];

};

//模拟memcpy的实现

void * mymemcpy(void *dest,const void *src,size_t n)

{

if (dest==NULL || src==NULL)

返回空值;

char * PDEst=static _ cast char *(dest);

const char * PSrc=static _ cast const char *(src);

if (pDest pSrc pDest pSrc n)

{

for(size _ t I=n-1;我!=-1;- i)

{

pDest[I]=PSrc[I];

}

}

其他

{

for(size _ t I=0;I n;I)

{

pDest[I]=PSrc[I];

}

}

返回dest

}

int main()

{

人stPeople1,stPeople2

memset((void*)stPeople1,0x00,sizeof(Stpeople 1));

memset((void*)stPeople2,0x00,sizeof(Stpeople 2));

stPeople1.iAge=32

mymemcpy(stPeople1.szName,' li lei ',sizeof(Stpeople 1 . SZ name));

mymemcpy(stPeople1.szSex,' man ',sizeof(stpeople 1 . szsex));

mymemcpy((void*)stPeople2,(void*)stPeople1,sizeof(Stpeople 2));

printf('此人年龄为%d,姓名为%s,性别为%s\n ',stPeople2.iAge,stPeople2.szName,Stpeople 2 . szsex);

返回0;

}

我们来看看mymemcpy的实现。此时是字节实现,但和strncpy实现不一样。让我们看看memcpy实现的注意事项:

同样,在函数入口检查源字符串指针和目标字符串指针是否为空,否则会出现意外错误;

因为是按一个字节复制的,所以需要将参数转换成char*类型才能操作;

要检查源内存和目标内存是否有内存重叠,如果目标内存的第一个地址在源内存的中间,就要从后向前复制,因为如果从前向后复制,从目标内存的第一个地址开始的地方就会被覆盖。如果没有重叠,或者源内存地址在目标内存中间,也没关系。

不能用' \0 '来判断复制结束,因为它是一整块内存的副本。举个简单的例子,如果你复制一个类似于上面代码的结构,它大概会在中间某个地方停止复制,这个复制相当于未完成;

同样,memcpy也返回目标字符串地址;

但是这个时候如果面试官让你按4字节抄,怎么实现呢?

按照前面的逻辑,其实按4字节复制就是把指针类型转换成int*来复制,但是有一点不同的是,如果按4字节复制,就没有办法判断内存重叠,因为内存的基本单位是一个字节,没有办法避免4字节的覆盖。可用的4字节复制码如下:

void * mymemcpy(void *dest,const void *src,size_t n)

{

if (dest==NULL || src==NULL)

返回空值;

int * PDEst=(int *)dest;

int * PSrc=(int *)src;

int iWordNum=n/4;

int ISlice=n % 4;

while(iWordNum -)

{

* pDest=* pSrc

}

char * pcDest=(char *)pDest;

char * pcSrc=(char *)PSrc;

while(iSlice -)

{

* pcDest=* pcSrc

}

返回dest

}

从4个字节来看,一个明确的思路是,满足4个字节就按int类型复制,不满足4个字节就按char类型复制。

tcp和udp的基本函数调用过程以及如何选择
« 上一篇
返回列表
下一篇 »
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
你会是第一个来这里评论的人吗?
最近发布资讯
更多