这里写目录标题

  • strcpy
  • memcpy
  • memset
  • strcmp
  • memcmp
  • 实现一个高效率的memcpy

strcpy

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

功能:把src所指由’\0’结束的字符串复制到dest所指的数组中。 src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

#include<string.h>
#include<iostream.h>void main(){char a[20],c[]="i am teacher!";
strcpy(a,c);
cout<<a<<endl;
}

此小例子中,char c[]={‘i’,’ ‘,‘a’,‘m’,’ ‘,‘t’,‘e’,‘a’,‘c’,‘h’,‘e’,‘r’,’\0’};字符串一般默认后面有一个结束符,当用到strcpy(a,c);函数时,把c中的字符串复制到a中,当遇到字符串中默认的结束符后,复制结束。

memcpy

原型:extern void *memcpy(void *dest, void *src, unsigned int count);

功能:由src所指内存区域复制count个字节到dest所指内存区域。 src和dest所指内存区域不能重叠,函数返回指向dest的指针。可以拿它拷贝任何数据类型的对象。

#include <stdio.h>
#include <string.h>
int main(){char *s="Golden Global View";//此字符串总共有18个字符,再加上一个结束符,总共存放19个字符char d1[20],d2[20];memcpy(d1,s,(strlen(s)+1));//用memcpy函数,把s中字符串的首地址拷贝到d中,连续复制19个字符memcpy(d2,s+14,5); //从第14个字符(V)开始复制,连续复制4个字符(View)printf("%d\n",strlen(s));printf("%s\n",d1);printf("%s\n",d2);return 0;}

memset

原型:extern void *memset(void *buffer, int c, int count);

功能:把buffer所指内存区域的前count个字节设置成字符c。用来对一段内存空间全部设置为某个字符。 返回指向buffer的指针。

#include <stdio.h>
#include <memory.h>#include <string.h>int main(){char s[]="Golden Global View";memset(s,'G',6);//把s中的前6个字符改成G,也就是把Golden改成GGGGGGprintf("%s\n",s);//输出为GGGGGG Global Viewreturn 0;}

strcmp

原型:extern int strcmp(const char *s1,const char *s2);

功能:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇’\0’为止。当s1<s2时,返回为负数;当s1=s2时,返回值= 0;当s1>s2时,返回正数。

memcmp

原型:extern int memcmp(const void *str1, const void *str2, size_t n);

功能:其功能是把存储区 str1 和存储区 str2 的前 n 个字节逐字节进行比较。该函数是按字节比较的,因此不能用于比较结构体

实现一个高效率的memcpy

memcpy的功能是从src的开始位置拷贝n个字节的数据到dest。如果dest存在数据,将会被覆盖。memcpy函数的返回值是dest的指针。memcpy函数定义在string.h头文件里。

自己实现的时候,最简单的方法是用指针按照字节顺序复制即可。但是性能太低,主要由以下两个原因:

  1. 一次一个字节效率太低,地址总线一般是32位,能搬运4字节,一次一个肯定慢的不行。
  2. 当内存区域重叠时会出现混乱情况。

一下根据以上两方面考虑提高memcpy函数的性能。

首先考虑速度,可以按照CPU位宽搬运数据,效率更高,代码如下:

void * Memcpy1(void *dst,const void *src,size_t num)
{int nchunks = num/sizeof(dst);   /*按CPU位宽拷贝*/cout<<"sizeof(dst)是:"<<sizeof(dst)<<endl;int slice =   num%sizeof(dst);   /*剩余的按字节拷贝*/unsigned long * s = (unsigned long *)src;unsigned long * d = (unsigned long *)dst;while(nchunks--)*d++ = *s++;while (slice--)*((char *)d++) =*((char *)s++);return dst;
}

sizeof(dst)是4,即大部分数据每次按照4字节拷贝,最后不足4字节的再分别拷贝。内存区域出现重叠时,这种方法无法规避内存混乱问题。下面的方法能够规避内存重叠的bug,代码如下:

void *Memcpy2(void *dest, const void *src, size_t count)   {    char
*d;    const char *s;  if (((int)dest > ((int)src+count)) || (dest < src))  {  d = (char*)dest;  s = (char*)src;  while (count--)  *d++ = *s++;          }    else /* overlap */  {  d = (char *)((int)dest + count - 1); /* 指针位置从末端开始,注意偏置 */  s = (char *)((int)src + count -1);  while (count --)  *d-- = *s--;  }  return dest;   }

如果检测到内存区域有重叠部分,则从末端开始对每个字节进行拷贝。

将两种方法结合后能够提高拷贝函数性能,代码如下:

void *Memcpy(void *dest, const void *src, size_t count)
{  cout<<"sizeof(dest)是:"<<sizeof(dest)<<endl;int bytelen=count/sizeof(dest);   /*按CPU位宽拷贝*/int slice=count%sizeof(dest);  /*剩余的按字节拷贝*/unsigned int* d = (unsigned int*)dest;  unsigned int* s = (unsigned int*)src;  if (((int)dest > ((int)src+count)) || (dest < src))  {  while (bytelen--)  *d++ = *s++;  while (slice--)  *(char *)d++ = *(char *)s++; }  else /* overlap重叠 */  {  d = (unsigned int*)((unsigned int)dest + count - 4); /*指针位置从末端开始,注意偏置 */  s = (unsigned int*)((unsigned int)src + count -4);  while (bytelen --)  *d-- = *s--;  d++;s++;char * d1=(char *)d;char * s1=(char *)s;d1--;s1--;while (slice --)  *(char *)d1-- = *(char *)s1--; }  return dest;
}

C++ strcpy,memcpy,memset,strcmp,memcmp相关推荐

  1. strcpy、memcpy和memset的区别

    strcpy 原型:extern char *strcpy(char *dest,char *src); 用法:#include <string.h> 功能:把src所指由NULL结束的字 ...

  2. 库函数strcpy、memcpy和memset

    编写一个函数,作用是把一个char组成的字符串循环右移n个. void LoopMove(char pStr, int steps) { int n = strlen(pStr) - steps; c ...

  3. 【c++】10. memset()、【strcpy_s()、memcpy_s()】、【strcpy(),memcpy()】

    选择使用[strcpy_s.memcpy_s]还是选择[strcpy,memcpy]? memset()的用法 memcpy_s,strcpy_s函数明确的指定了目标内存的大小,能够清晰的暴露出内存溢 ...

  4. c语言memcpy与strcpy,C语言:strcpy()和memcpy()

    一.strcpy和memcpy都是标准C库函数,它们有下面的特点: 1.strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符. 已知st ...

  5. strcpy()和memcpy()的区别

    Strcpy和memcpy都可以用来拷贝字符串,strcpy以\0结束,但memcpy必须指定拷贝的长度,类似于strncpy Strncpy与memcpy类似,区别是:当遇到\0时,strncpy停 ...

  6. strlen函数,strcpy函数,strcat函数,memset函数,strcmp函数,memcpy函数,memove()函数

    文章目录 一,strlen函数(库函数头文件<string.h>) 二,strcpy函数(库函数头文件<string.h>)拷贝函数 三,strcat函数(头文件是<st ...

  7. 细谈C语言中的strcpy,strncpy,memcpy,memmove,memset函数

    一.函数介绍: 1.memcpy 函数原型:extern void *memcpy(void *dest, const void *src, size_t count); 用法:#include< ...

  8. 工作的准备:atoi,itoa,strcpy,memcpy,strcmp,二分查找,strcat

    对常见的几个函数,周末没事写写,绝对是笔试面试中非频繁,前面n届学长无数次强调了,大家就别怀疑了.从今天开始,每天10道题. int atoi(const char* str) {if(str==NU ...

  9. C语言常用字符串操作函数大全详解(strstr,strtok,strrchr,strcat,strcmp,strcpy,strerror,strspn,strchr等)

    参考:string.h中常用字符串操作函数说明(strstr,strtok,strrchr,strcat,strcmp,strcpy,strerror,strspn,strchr等) 作者:一只青木呀 ...

最新文章

  1. 【职场】面试中最难回答频率最高的70个问题
  2. 这是一款深受学生党喜爱的PDF阅读器
  3. matlab dist函数
  4. 27款经典网站设计必备的CSS框架
  5. 64 位SQL Server 2005通过DB link链接32位SQL Server 2000 的bug解决
  6. 博科光纤交换机操作手册之三
  7. redis 入门指南第二版 学习记录3 列表类型
  8. ubuntu1804下txt文件乱码问题
  9. 网口压线顺序_网线怎么接头 网线水晶头的接法和排序
  10. .net core mvc中使用ef
  11. 01背包, 完全背包,多重背包
  12. 室内全景图数据集的设计及制作流程
  13. 3D图形学一:模仿草的运动 – GPU(Pixel Shader Vertex Shader)实现
  14. Leaflet 可视化--风场、海浪、洋流、气压、温度等
  15. 【HTML502】HTML基础02_标题_段落_文本格式化_链接
  16. Spring事务管理-》Spring事务管理(annotation)
  17. c语言专业认知实践报告怎么写,C语言课程设计实习报告范本
  18. 域服务器禁用无线,无线域服务常见问题
  19. 技术交流电脑BUG.sssss
  20. 四、Zabbix监控-Web

热门文章

  1. 日语音频转换成日文怎么弄?这几款软件轻松实现
  2. Geoframe教程2——加载地震数据
  3. 在地质区划图上绘制伪震中
  4. MongoDB使用详解_4_常用聚合操作详解
  5. Linux系统测试工具-转
  6. RationalDMIS 2020测量圆
  7. 单反后键对焦的使用技巧
  8. 部署测试环境(非常详细哦,不看会后悔的操作步骤)
  9. 【leetcode刷题记录】69x的平方根
  10. HashMap源码深度解析【重点】