• 字符串和内存函数(2)


    2.13 memcpy

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

    • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
    • 这个函数在遇到 ‘\0’ 的时候并不会停下来。
    • 如果source和destination有任何的重叠,复制的结果都是未定义的。
    • 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

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

    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    memcpy拷贝重叠的内存空间
    因此,memcpy函数是用来处理不重叠的内存拷贝的。

    2.14 memmove

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

    • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
    • 如果源空间和目标空间出现重叠,就得使用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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    memmove的模拟实现:
    memmove模拟实现示意图

    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    2.15 memcmp

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

    • 比较从ptr1和ptr2指针开始的num个字节
    • 返回值如下:
      memcmp返回值
    #include 
    #include 
    
    int main()
    {
    	int arr1[] = { 1, 2, 1, 4, 5, 6 };
    	int arr2[] = { 1, 2, 257 };
    	
    	//int ret = memcmp(arr1, arr2, 9);
    	//printf("%d\n", ret);//0
    	
    	int ret = memcmp(arr1, arr2, 10);
    	printf("%d\n", ret);//-1
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    arr1数组在内存中的存储
    arr2数组在内存中的存储

    2.16 memset

    void* memset(void* ptr, int value, size_t num);

    #include 
    #include 
    
    int main()
    {
    	char arr[] = "hello bit";
    	memset(arr + 1, 'x', 4);//以字节为单位设置的
    	printf("%s\n", arr);//hxxxx bit
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #include 
    
    int main()
    {
    	int arr[10] = { 0 };
    	memset(arr, 1, 10);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    memset结果

  • 相关阅读:
    QT5 实现 SFTP 上传和下载文件
    离散数学(十二):关系的幂运算与关系的性质
    二极管选型指南
    java计算机毕业设计基于安卓Android的校园单车租赁App
    v-model修饰符 .lazy .number .trim
    神经网络基础
    【springboot】9、Rest风格请求及视图解析
    react ant design Upload 多文件上传 beforeUpload 会调用很多次,怎么只获取一次
    大语言模型量化方法对比:GPTQ、GGUF、AWQ
    dos2unix命令
  • 原文地址:https://blog.csdn.net/weixin_73077334/article/details/134525296