深入了解strcpy和memcpy的区别
void *memcpy(void *dest, const void *src, int n);
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中#include
函数返回一个指向dest的指针。
1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。
2.与strcpy相比,memcpy并不是遇到" "就结束,而是一定会拷贝完n个字节。
3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
//注意,source和destin都不一定是数组,任意的可读写的空间均可。---wk
strcpy函数的实现:
已知strcpy函数的原型是:char *strcpy(char *dst, const char *src);实现strcpy函数解释为什么要返回char *假如考虑dst和src内存重叠的情况,strcpy该怎么实现
1.strcpy的实现代码char * strcpy(char *dst,const char *src) //[1] { assert(dst != NULL && src != NULL); //[2] char *ret = dst; //[3] while ((*dst++=*src++)!=" "); //[4] return ret; } ############################### //或者 ############################### void* my_strcpy(void *arr, void *brr) { int j = 0; int k = 0; while(brr[j] != 0) { arr[j] = brr[j]; j++; } arr[j] = " "; return arr; }
[1]const修饰
源字符串参数用const修饰,防止修改源字符串。
[2]空指针检查
(A)不检查指针的有效性,说明答题者不注重代码的健壮性。
(B)检查指针的有效性时使用assert(!dst && !src);
char *转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。
(C)检查指针的有效性时使用assert(dst != 0 && src != 0);
直接使用常量(如本例中的0)会减少程序的可维护性。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。
[3]返回目标地址
(A)忘记保存原始的strdstt值。
[4]" "
(A)循环写成while (*dst++=*src++);明显是错误的。
(B)循环写成while (*src!=" ") *dst++=*src++;
循环体结束后,dst字符串的末尾没有正确地加上" "。
2.为什么要返回char *?
返回dst的原始值使函数能够支持链式表达式。
链式表达式的形式如:int l=strlen(strcpy(strA,strB))
又如:char * strA=strcpy(new char[10],strB);
返回strSrc的原始值是错误的。
其一,源字符串肯定是已知的,返回它没有意义。
其二,不能支持形如第二例的表达式。
其三,把const char *作为char *返回,类型不符,编译报错。
3.假如考虑dst和src内存重叠的情况,strcpy该怎么实现
char s[10]="hello";
strcpy(s, s+1); //应返回ello,
//strcpy(s+1, s); //应返回hhello,但实际会报错,因为dst与src重叠了,把" "覆盖了
所谓重叠,就是src未处理的部分已经被dst给覆盖了,只有一种情况:src<=dst<=src+strlen(src)
C函数memcpy自带内存重叠检测功能,下面给出memcpy的实现my_memcpy。char * strcpy(char *dst,const char *src) { assert(dst != NULL && src != NULL); char *ret = dst; my_memcpy(dst, src, strlen(src)+1); return ret; }
my_memcpy的实现如下char *my_memcpy(char *dst, const char* src, int cnt) { assert(dst != NULL && src != NULL); char *ret = dst; if (dst >= src && dst <= src+cnt-1) //内存重叠,从高地址开始复制 { dst = dst+cnt-1; src = src+cnt-1; while (cnt--) *dst-- = *src--; } else //正常情况,从低地址开始复制 { while (cnt--) *dst++ = *src++; } return ret; }
memcpy思想:大部分认为memcpy是一个char到char的拷贝循环,担心它的效率。
实际上,memcpy是一个效率最高的内存拷贝函数,他不会那么傻来做一个一个字节的内存拷贝,
在地址不对齐的情况下,他是一个字节一个字节的拷,地址对齐以后,就会使用CPU字长来拷,32bit或64bit,
还会根据CPU的类型选择一些优化的指令来进行拷贝。总的来说,memcpy的实现是CPU类型、操作系统、cLib相关的。毫无疑问,它是内存拷贝里效率最高的,可以放心使用。void *mymemcpy(void *dst, const void *src, size_t num) { assert((NULL != dst) && (NULL != src)); int wordnum = num / 4; //计算有多少个32位,按4字节拷贝 int slice = num % 4; //剩余的按字节拷贝 int *pintsrc = (int *)src; //强制转换类型,不同类型的不能进行拷贝 int *pintdst = (int *)dst; while(wordnum--) { *pintsrc++ = *pintsrc++; } while(slice--) { ((char *)pintdst++) = *((char *)pintsrc++); } return dst; }
strcpy和memcpy都是标准C库函数,它们有下面的特点。
strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。
已知strcpy函数的原型是:char* strcpy(char* dest, const char* src);
memcpy提供了一般内存的复制。即memcpy对于需要复制的内容没有限制,因此用途更广。void *memcpy( void *dest, const void *src, size_t count ); char * strcpy ( char * dest, const char * src) // 实现src到dest的复制 { if ((src == NULL) || (dest == NULL)) //判断参数src和dest的有效性 { return NULL; } char *strdest = dest; //保存目标字符串的首地址 while ((*strDest++ = *strSrc++)!= " " ); //把src字符串的内容复制到dest下 return strdest; } void * memcpy ( void *memTo, const void *memFrom, size_t size) { if ((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必须有效 return NULL; char *tempFrom = ( char *)memFrom; //保存memFrom首地址 char *tempTo = ( char *)memTo; //保存memTo首地址 while (size -- > 0) //循环size次,复制memFrom的值到memTo中 *tempTo++ = *tempFrom++ ; return memTo; }
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符" "才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
简述strcpy与memcpy的相同点和区别点
相同点:strcpy与memcpy都可以实现拷贝的功能
不同点:
(1)实现功能不同,strcpy主要实现字符串变量间的拷贝,memcpy主要是内存块间的拷贝。
(2)操作对象不同,strcpy的操作对象是字符串,memcpy 的操作对象是内存地址,并不限于何种数据类型。
(3)执行效率不同,memcpy最高,strcpy次之。
一则数据出炉,华为鸿蒙或抢占安卓份额,谷歌安卓受到挑战高端科技,要是没有了芯片,就等于没有了最主要的灵魂,在智能手机方面,要是没有了操作系统,那就等同于没有了主心骨,操作系统的重要性可见一斑,目前,在国际智能手机操作系统市场中,一直以
为什么中国芯片制造业被卡脖子?有没有解决办法?大家都知道,现在芯片贵,而且很难造,到底难在哪呢,为什么我们会在这个技术上被人卡脖子呢首先给大家讲讲芯片到底是什么东西芯片又叫微处理器,用来运算的,好比是电脑的大脑。英特尔在197
三大运营商日均赚3。87亿元原标题三大运营商日均赚3。87亿元(主题)一季度营收总额为4348。98亿元(副题)近日,三大运营商均公布了今年一季度的财报。在今年的第一季度,三大运营商合计实现营收总额为4348
哈啰换logo引热议,自称没有百万设计,网友雷军听了都得哭4月25日,据哈啰官微消息,哈啰品牌升级,并更换了新的logo。从哈啰的Logo变动来看,其品牌名称去掉出行二字,并用哈啰文字代替图形H。图源哈啰官微对于更换logo,有网友在哈啰
马斯克收购推特之谜他还能从哪里获得210亿美元?据外媒报道,美东时间4月25日,ElonMusk和TwitterInc。达成协议,马斯克计划以440亿美元收购社交网络平台Twitter。不过在马斯克方面,目前仍然存在一个问题待解
旗舰手机和其他手机的区别,旗舰手机都有哪些独特配置和特点?VivoX80Pro的配置确实拉得很满,由此我们也看到了目前顶级旗舰手机的几种顶级体验配置。12K分辨率的三星E5曲屏,LTPO技术加持下的1120Hz的自适应刷新率,可以说,旗舰
NavitasGaNIC驱动Vivo可折叠手机GaN芯片公司NavitasSemiconductor宣布,其采用GaNSense技术的下一代GaNFast电源IC已被选中为Vivo新发布的首款折叠屏旗舰产品XFold内置80W
涉嫌隐私不合规,这17款App被通报!你手机里有吗?国家计算机病毒应急处理中心近期通过互联网监测发现17款移动App存在隐私不合规行为,违反网络安全法个人信息保护法等相关规定,涉嫌超范围采集个人隐私信息。1未向用户明示申请的全部隐私
小米不值得买的4款手机小米不值得买的4款手机这四款小米手机千万别碰,最后一款你绝对想不到。第一款红米k40proplus除了相机升级了超大杯,还升级了啥?3299的售价毫无性价比,有这一算还不如选小米1
电竞手机怎么选这台iQOONeo6真香一说到电竞手机,大家想到了什么?机甲风外观?RGB灯效?IP联名?甚至透明壳的极客风?更多人买电竞手机还是为了当主力机用的,并不想让它看起来太张扬,希望看起来更轻便更漂亮!性能固然
电视春季新品上市步入尾声大屏游戏电视热度不减新京报贝壳财经讯(记者陈维城)春季是彩电新品上市的旺季,近期以来,海信创维康佳TCL等电视企业纷纷推出电视新品。据奥维云网研究整理可知,今年彩电新品除了对去年的产品布局进行常规的迭