字符串和内存函数(2)
作者:mmseoamin日期:2023-12-05

文章目录

      • 2.13 memcpy
      • 2.14 memmove
      • 2.15 memcmp
      • 2.16 memset

        2.13 memcpy

        void* memcpy(void* destination, const void* source, size_t num);

        • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
        • 这个函数在遇到 ‘
        • 如果source和destination有任何的重叠,复制的结果都是未定义的。
        • ’ 的时候并不会停下来。memcpy函数
        • memcpy是内存拷贝,它可以拷贝字符串、整型数组、结构体数组等多种类型,所以要用void*的指针来接收。
          #include 
          #include 
          int main()
          {
          	int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
          	int arr2[20] = { 0 };
          	//将arr1中的内容,拷贝到arr2中
          	memcpy(arr2, arr1, 40);
          	//     int*  int*
          	int i = 0;
          	for (i = 0; i < 20; i++)
          	{
          		printf("%d ", arr2[i]);//1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0
          	}
          	return 0;
          }
          
          #include 
          #include 
          int main()
          {
          	float arr1[] = { 1.0, 2.0, 3.0 };
          	float arr2[5] = { 0 };
          	//将arr1中的内容,拷贝到arr2中
          	memcpy(arr2, arr1, 8);
          	//    float* float*
          	int i = 0;
          	for (i = 0; i < 5; i++)
          	{
          		printf("%f ", arr2[i]);//1.000000 2.000000 0.000000 0.000000 0.000000
          	}
          	return 0;
          }
          

          memcpy的模拟实现:

          #include 
          #include 
          //函数拷贝结束后,返回目标空间的起始地址
          void* my_memcpy(void* dest, const void* src, size_t num)
          {
          	void* ret = dest;
          	assert(dest && src);
          	while (num--)
          	{
          		*(char*)dest = *(char*)src;
          		dest = (char*)dest + 1;
          		src = (char*)src + 1;
          		//强制类型转换是临时的,不是永久的
          	}
          	return ret;
          }
          int main()
          {
          	int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
          	int arr2[20] = { 0 };
          	my_memcpy(arr2, arr1, 20);
          	int i = 0;
          	for (i = 0; i < 20; i++)
          	{
          		printf("%d ", arr2[i]);//1 2 3 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
          	}
          	return 0;
          }
          

          如果目标空间和源头空间有重合,就会出现以下情况:

          #include 
          #include 
          //函数拷贝结束后,返回目标空间的起始地址
          void* my_memcpy(void* dest, const void* src, size_t num)
          {
          	void* ret = dest;
          	assert(dest && src);
          	while (num--)
          	{
          		*(char*)dest = *(char*)src;
          		dest = (char*)dest + 1;
          		src = (char*)src + 1;
          		//强制类型转换是临时的,不是永久的
          	}
          	return ret;
          }
          int main()
          {
          	int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
          	my_memcpy(arr1 + 2, arr1, 20);
          	int i = 0;
          	for (i = 0; i < 10; i++)
          	{
          		printf("%d ", arr1[i]);//1 2 1 2 1 2 1 8 9 10
          	}
          	return 0;
          }
          

          字符串和内存函数(2),memcpy拷贝重叠的内存空间,第1张

          因此,不重叠是用来处理

          2.14 memmove

          的内存拷贝的。

        • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
        • void* memmove(void* destination, const void* source, size_t num);

            2.15 memcmp

          • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
            #include 
            #include 
            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 ", arr1[i]);//1 2 1 2 3 4 5 8 9 10
            	}
            	return 0;
            }
            

            memmove的模拟实现:

            字符串和内存函数(2),memmove模拟实现示意图,第2张

            #include 
            #include 
            void* my_memmove(void* dest, const void* src, size_t num)
            {
            	void* ret = dest;
            	assert(dest && src);
            	if (dest < src)
            	{
            		//前->后
            		while (num--)
            		{
            			*(char*)dest = *(char*)src;
            			dest = (char*)dest + 1;
            			src = (char*)src + 1;
            		}
            	}
            	else
            	{
            		//后->前
            		while (num--)
            		{
            			*((char*)dest + num) = *((char*)src + num);
            		}
            	}
            	return ret;
            }
            int main()
            {
            	int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            	my_memmove(arr1 + 2, arr1, 20);//1 2 1 2 3 4 5 8 9 10
            	//my_memmove(arr1, arr1 + 2, 20);//3 4 5 6 7 6 7 8 9 10
            	int i = 0;
            	for (i = 0; i < 10; i++)
            	{
            		printf("%d ", arr1[i]);
            	}
            	return 0;
            }
            
            字节

            int memcmp(const void* ptr1, const void* ptr2, size_t num);