memset,memcmp,memmove,memcpy浅析笔记以及与字符串处理函数strcmp,strcpy等的区别分析

目录:

  1. memeset,memcmp,memmove,memcpy函数作用以及使用时注意的地方。
  2. 与strcpy,strncpy,strcmp,strncmp,strcasemp("abc","ABC")区别。

一.内存处理函数。

1.memset 函数作用。

memset的作用是把指定的一段内存设置为第二个参数指定的值。 memset(内存地址,要设置的数,字节数)。memset是按照字节赋值的。

memset(内存地址,1,字节数)这个函数的功能就是以内存地址为开始,长度为字节数的空间 每个字节赋值为1。

下面程序是讲数组空间原来数组元素值重新赋值为0,memset一般用于对申请的空间进行初始化为0,不让它以随机值的方式出现。

int a[]={1,2,3,4,5,6,7,8};
int size = sizeof(a);
memset(a,0,size);
for(int i= 0;i

需要注意的问题:memset是字节为单位赋值!但是我们绝大时候数据都不是一个字节,所以这时候的赋值会出现问题。赋值一个字节,但是取值的时候是按照类型大小。

int data[10];
memset(data, 0, sizeof(data));    //正确
memset(data, -1, sizeof(data));    // 正确
memset(data, 1, sizeof(data));    // 错误 一个data[i]实际的值是 0x0101,而不是1 

2.memcmp作用

作用:Compare characters in two buffers. 比较两个缓冲区 count字节大小的内容

函数原型:int memcmp( const void *buf1, const void *buf2, size_t count );

返回值:

当buf1

当buf1=buf2时,返回值=0

当buf1>buf2时,返回值>0

void main( void )
{
   char first[]  = "12345678901234567890";
   char second[] = "12345678901234567891";
   int result;

   printf( "Compare '%.19s' to '%.19s':\n", first, second );
   result = memcmp( first, second, 19 );  //比较前19位
   if( result < 0 )
      printf( "First is less than second.\n" );
   else if( result == 0 )
      printf( "First is equal to second.\n" );
   else if( result > 0 )
      printf( "First is greater than second.\n" );
   printf( "Compare '%.20s' to '%.20s':\n", first, second );
   result = memcmp( first, second, 20 ); //比较20位,此时因为fisrt的 ‘0’ < second的‘1’,所
  //以result<0
   if( result < 0 )
      printf( "First is less than second.\n" );
   else if( result == 0 )
      printf( "First is equal to second.\n" );
   else if( result > 0 )
      printf( "First is greater than second.\n" );
}

输出:

Compare '1234567890123456789' to '1234567890123456789':
First is equal to second.
Compare '12345678901234567890' to '12345678901234567891':
First is less than second.

需要注意问题是:memcmp() 函数也是以一个字节大小比较,遇到第一个不等于,或大或小就会返回。如果count次数大于了buf1或buf2的空间大小,memcmp也不会在'\0'处结束,依旧会继续比较,直至count次数用完或者是返回值不为0(此时比较出来结果,但是不是正确的)。

3.memcpy()函数,和memmove()函数

memcpy()作用:Copies characters between buffers. 拷贝count字节大小从src空间到dest中。

函数原型:void *memcpy( void *dest, const void *src, size_t count );

摘要:The memcpy function copies count bytes of src to dest. If the source and destination overlap, this function does not ensure that the original source bytes in the overlapping region are copied before being overwritten. Use memmove to handle overlapping regions.

解释: memcpy函数将src的字节数复制到dest,如果源字节数和目标字节数重叠,该函数不能保证重叠区域的原始源字节数在被覆盖之前被复制。使用memmove处理重叠区域。可见memcpy()函数不保证copy的正确性。 同样copy也是一个字节一个字节拷贝的。

memmove()作用: Moves one buffer to another. 作用是一个一个buff到另外一个buf

函数原型: void *memmove( void *dest, const void *src, size_t count );

memcpy与memmove函数对比:

  1. memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝count个字节到目标dest所指的内存地址的起始位置中。
  2. memmove函数的功能同memcpy基本一致,但是当src区域和dst内存区域重叠时,memcpy可能会出现错误,而memmove能正确进行拷贝。

拷贝情况空间的情况:

   可分为三种情况:

  1. 源src空间与目的dest空间完全不重叠。
  2. 当源src与目的dest空间重叠而且源src空间在目的dest空间后面。
  3. 当源src与目的dest空间重叠而且源src空间在目的dest空间前面。

前面两种情况,memcpy()可以进行正常copy,第三种情况memcpy()拷贝时会讲数据破坏,src前面数据会覆盖后面重叠部分的数据。第三种情况由memmove()函数处理,具体做法是从后往前cpy,从src的末端向前copycount个字节大小空间。

下面结合例子演示各种情况:(代码为msdn中的源码, 每个句子后都有一个解释)

char string1[60] = "The quick brown dog jumps over the lazy fox";
char string2[60] = "The quick brown fox jumps over the lazy dog";
/*                           1         2         3         4         5
 *                  12345678901234567890123456789012345678901234567890
 */

void main( void )
{
   printf( "Function:\tmemcpy without overlap\n" ); //没有内存重叠的
   printf( "Source:\t\t%s\n", string1 + 40 );   //源字符串从string1下标为40的开始
   printf( "Destination:\t%s\n", string1 + 16 );//目的地址从string1下标为16的开始
   memcpy( string1 + 16, string1 + 40, 3 ); //将dog替换为了fox
   printf( "Result:\t\t%s\n", string1 ); //打印结果
   printf( "Length:\t\t%d characters\n\n", strlen( string1 ) ); //求string1长度。不变为43

   /* Restore string1 to original contents */ // 把数组恢复到原来未拷贝前
   memcpy( string1 + 16, string2 + 40, 3 );

   printf( "Function:\tmemmove with overlap\n" );  //用memmove处理函数
   printf( "Source:\t\t%s\n", string2 + 4 );       //源字符串为string2下标为4的开始
   printf( "Destination:\t%s\n", string2 + 10 );  //目的字符串为string2下标为10的开始
   memmove( string2 + 10, string2 + 4, 40 ); //此种情况为源地址在目的地址之前。
   printf( "Result:\t\t%s\n", string2 ); 
   printf( "Length:\t\t%d characters\n\n", strlen( string2 ) ); //49

   printf( "Function:\tmemcpy with overlap\n" ); //用memcpy()函数应对内存重叠
   printf( "Source:\t\t%s\n", string1 + 4 ); 
   printf( "Destination:\t%s\n", string1 + 10 );
   memcpy( string1 + 10, string1 + 4, 40 ); //此种情况为源地址在目的地址之前。会发现copy错误
   printf( "Result:\t\t%s\n", string1 );
   printf( "Length:\t\t%d characters\n\n", strlen( string1 ) ); //49 
}

二.字符串处理函数。

1.memcpy,memmove与字符串函数strcpy区别:

  • memcpy与memmove都是对内存进行拷贝可以拷贝任何内容,而strcpy仅是对字符串进行操作。
  • memcpy与memmove拷贝多少是通过其第三个参数进行控制而strcpy是当拷贝至'\0'停止。

strncpy拷贝n个字节大小的字符。此时也会有内存的重叠问题。在函数实现的内部,需要对地址进行判断,看是否发生重叠。

2.memcmp与strcmp,strncmp()联系与区别:

  1. 字符串处理函数都会以'\0'结束,而memcmp是必须比出大小或者比较完count次数。
  2. strcmp未设定比较位数,直至到'\0'结束。

 

3.strcasecmp函数与strncasecmp函数:用来比较两个字符串,忽略大小写。n则是比较n个字节大小。

返回值:

  1. 若参数s1和s2字符串相同则返回0。
  2. s1长度大于s2长度则返回大于0 的值。
  3. s1 长度若小于s2 长度则返回小于0的值。

此篇文章只是简单的对这些函数做了简单的介绍以及使用的一些注意点,更好的学习方法应该是学习这些函数的内部实现。自己动手实现一些。

 

你可能感兴趣的:(C/C++)