C language memory functions memcpy, memmove, memset, memcmp

 ---------------------------------------------

The night will inevitably be dark and cool, but there will be dawn as we move forward.

-------------Today I will take you to understand the memory functions in C language

---------Usage and simulation implementation

-----The header files of these functions are still included#include<string.h>

Table of contents

Use of memcpy function

Simulation implementation of memcpy function

Use of memmove function 

Simulation implementation of memmove function 

 Use of memset function

 Use of memcmp function


Use of memcpy function

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

1. The function memcpy starts from the position of cource and copies backwardsnum bytes data to the memory location pointed to by destination

2. The function memcpy will not stop when encountering '\0', < a i=3>You can still copy the position after '\0'

3. Source and destination cannot overlap

4. Often used to copy non-string types

 The following is the general usage of the memcpy function:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
	int str[10] = { 0 };
	memcpy(str,arr , 20);
//内存函数的单位是字节,20字节就是5个整形元素
//也可以这么写memcpy(str,arr,5*sizeof(int))
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", str[i]);
	}
	return 0;
}

Let's verify whether memcpy will not stop when it encounters '\0': 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "Hel\0lo World!";
	char str[10] = { 0 };
	memcpy(str, arr, 6 * sizeof(char));
	for (int i = 0; i < 6; i++)
	{
		printf("%c", str[i]);
	}
	return 0;
}

We can see that the memcpy function doesnot stop because it encounters '\0', it /span>Copy '\0' to the target function

Simulation implementation of memcpy function

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void* my_memcpy(void* arr, const void* str, size_t num)
         //因为这个函数可以运用到多种类型,所以用了void*(无具体类型的指针)
{
	void* ret = arr;
	while (num--)
	{
		*(char*)arr = *(char*)str;
		arr = (char*)arr+1;   
		str = (char*)str + 1;
//强制类型转换为char类型可以一个字节一个字节的访问
	}
	return ret;
//返回目标函数的起始地址
}
int main()
{
	char arr[] = { 1,3,5,7,9,2,4,6,8,0 };
	char str[10] = { 0 };
	my_memcpy(str, arr, 5 * sizeof(int));
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", str[i]);
	}
	return 0;
}

 Overlapping copy problem in memcpy:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void* my_memcpy(void* arr, const void* str, size_t num)
{
	void* ret = arr;
	while (num--)
	{
		*(char*)arr = *(char*)str;
		arr = (char*)arr + 1;
		str = (char*)str + 1;
	}
return ret;
}
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	my_memcpy(arr+3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

The memcpy in the library function of VS2022 can be overlapped and copied, but some compilers cannot

In order to show the distinction, we will not use memcpy for overlapping copies in the future.

You can usememmove function to achieveoverlapping copy

Use of memmove function 

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

 1. The difference between memmove and memcpy is thatsource space can be combined with target space Overlap

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	memmove(arr+3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

We can find that memmove has solved the problem of overlapping between the source space and the target space just now.

Next let us see how it is implemented

Simulation implementation of memmove function 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void* my_memmove(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	if (dst <= src || (char*)dst >= ((char*)src + count)) {
		while (count--) {
                  //从前向后拷贝
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else {
                  //从后向前拷贝
		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;
}
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	my_memmove(arr + 3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

Next, I will help you understand in the form of drawings:

 Use of memset function

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

1.memsrt is often used by us to set the memory to set the value in the memory to the desired content in bytes. 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "hello world";
	memset(arr, 'x', 6);
	printf(arr);
	return 0;
}

 In this way, we can see whether we have set the content of hello to "x"! This is the usage scenario of the memset function.

 Use of memcmp function

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

1. Compareptr1 and ptr2 pointer points starting from, backwardsnum words section 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "abcdfe";
	char str[] = "abcdefg";
	int n;
	n = memcmp(arr, str, sizeof(arr));
	if (n > 0)
		printf("'%s' 大于 '%s'.\n",arr ,str );
	else if (n < 0)
		printf("'%s' 小于 '%s'.\n", arr,str );
	else
		printf("'%s' 等于 '%s'.\n",arr ,str );
	return 0;
}

 That’s it for today’s introduction!

I will sort out the knowledge points about structures in the future.

I hope you will pay attention to it for a long time!

Thanks for the support

Guess you like

Origin blog.csdn.net/2301_79201049/article/details/134635408