目录
一.memcpy使用和模拟实现(内存拷贝)
二.memmove 使用和模拟实现
三.memset 函数的使用(内存设置)
四.memcmp 函数的使用
C语言中规定:
- memcpy拷贝的就是不重叠的内存
 - memmove拷贝的就是重叠的内存
 - 但是在VS2022 memcpy也可以实现重叠拷贝
 
一.memcpy使用和模拟实现(内存拷贝)
void * memcpy ( void * destination, const void * source, size_t num ); 
- 拷贝整型数据、字符数据、结构体数据
 - 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
 - 这个函数在遇到 '\0' 的时候并不会停下来。
 - 如果source和destination有任何的重叠,复制的结果都是未定义的。
 
#include <stdio.h>
#include <string.h>
int main()
{
 int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
 int arr2[10] = { 0 };
 memcpy(arr2, arr1, 20);//将1 2 3 4 5拷贝到arr2中,若将4 5 6 7 8放入,则为arr1+3
 int i = 0;          |  
                   //s*sizeof(int)
 for (i = 0; i < 10; i++)
 {
    printf("%d ", arr2[i]);
 }
 return 0;
}
//1 2 3 4 5 0 0 0 0 0  
 
 对于重叠的内存,交给memmove来处理。  
 
 
 memcpy函数的模拟实现: 
 
void * memcpy ( void * dst, const void * src, size_t count)
{
  void * ret = dst;
  assert(dst);
  assert(src);
  /*
  * copy from lower addresses to higher addresses
  */
  while (count--) {
    *(char *)dst = *(char *)src; //(char*)为一个字节,这里为临时强制转换的,故下面也要强制转换
    dst = (char *)dst + 1;
    src = (char *)src + 1;
  }
 return(ret);
} 
 
二.memmove 使用和模拟实现
void * memmove ( void * destination, const void * source, size_t num ); 
 - 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
 - 如果源空间和⽬标空间出现重叠,就得使用memmove函数处理。
 
#include <stdio.h>
#include <string.h>
int main()
{
 int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
 memmove(arr1+2, arr1, 20);
 int i = 0;
 for (i = 0; i < 10; i++)
 {
   printf("%d ", arr2[i]);
 }
 return 0;
} 
 
 输出的结果:  
 
1 2 1 2 3 4 5 8 9 10 
拷贝顺序分类:


 
 memmove的模拟实现:  
 
void * memmove ( void * dst, const void * src, size_t count)
{
 void * ret = dst;
 if (dst <= src || (char *)dst >= ((char *)src + count)) { 
        |
     //在其左边,前->后
    /*
    * Non-Overlapping Buffers
    * copy from lower addresses to higher addresses
    */
    while (count--) {
       *(char *)dst = *(char *)src;
       dst = (char *)dst + 1;
       src = (char *)src + 1;
    }
 }
 else { //后->前
    /*
     * Overlapping Buffers
     * copy from higher addresses to lower addresses
     */
     dst = (char *)dst + count - 1;
     src = (char *)src + count - 1;
     while (count--) {
       *(char *)dst = *(char *)src;
       dst = (char *)dst - 1;
       src = (char *)src - 1;
     }
 }
 return(ret);
} 
  
 三.memset 函数的使用(内存设置)
void * memset ( void * ptr, int value, size_t num ); 
 memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。
#include <stdio.h>
#include <string.h>
int main ()
{
 char str[] = "hello world";
 memset (str,'x',6);
 printf(str);
 return 0;
} 
 输出的结果:
xxxxxxworld 
  
 四.memcmp 函数的使用
int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 
 - ⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节
 - 返回值如下:
 

#include <stdio.h>
#include <string.h>
int main()
{
  char buffer1[] = "DWgaOtP12df0";
  char buffer2[] = "DWGAOTP12DF0";
  int n;
  n = memcmp(buffer1, buffer2, sizeof(buffer1));
  if (n > 0) 
    printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
  else if (n < 0) 
    printf("'%s' is less than '%s'.\n", buffer1, buffer2);
  else
    printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
 return 0;
} 
                


















