[Simulación feliz]: implemente funciones memcpy y memmove con simulación C

contenido

1. Introducción a la función memcpy

1. Declaración de función

2. Funciones y precauciones

3. Uso de funciones

Segundo, simule la implementación de la función memcpy

1. Análisis de simulación

2. Implementación de simulación

En tercer lugar, la introducción de la función memmove.

1. Declaración de función

2. ¿Por qué hay una función memmove?

3. Funciones y precauciones

4. Uso de funciones

Cuarto, simule la implementación de la función memmove

1. Análisis de simulación

 2. Implementación de simulación

Resumir


1. Introducción a la función memcpy

1. Declaración de función

void * memcpy ( void * destino, const void * origen, size_t num );

2. Funciones y precauciones

  • La función memcpy copia números bytes de datos hacia atrás desde la ubicación de origen a la ubicación de memoria de destino.
  • Tenga en cuenta que esta función no se detiene cuando encuentra '\0' .
  • Si hay alguna superposición entre el origen y el destino, el resultado de la copia es indefinido.
  • La función memcpy puede copiar cualquier tipo de datos, a diferencia de la función strcpy que solo puede copiar cadenas.

3. Uso de funciones

#include <stdio.h>
#include <string.h>//使用memcpy函数时记得引用它的头文件
int main()
{
	int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int arr2[5] = { 0 };//总共大小为20字节
	memcpy(arr1, arr2, 20//拷贝20个字节的数据);//将arr2中的数据拷贝到arr1中
	int i = 0;
	printf("拷贝后arr1中的数据为:");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

resultado de la operación:

Segundo, simule la implementación de la función memcpy

1. Análisis de simulación

1. Debido a que no sabemos qué tipo de datos queremos copiar, pueden ser datos de tipo char, datos de tipo int o datos de tipo doble. Los tamaños de estos diferentes tipos de datos son diferentes. Para implementar una función memcpy que pueda copiar todo tipo de datos, solo podemos copiar byte por byte, porque el tamaño del tipo más pequeño es un byte, por lo que se pueden copiar todos los tipos de datos.

2. Como no sabemos qué tipo de dirección se pasa a la función memcpy, usamos un puntero de tipo void* para recibir la dirección pasada.

3. Dado que solo necesitamos copiar los datos almacenados en la dirección de origen a la dirección de destino, solo necesitamos cambiar el contenido almacenado en la dirección de destino, no la dirección almacenada en la dirección de origen. Entonces necesitamos usar un puntero de tipo const void* para recibir la dirección de origen.

4. Para lograr el acceso encadenado, debemos devolver la dirección de inicio de destino (destino) que se pasó. Dado que esta función cambiará el contenido del almacenamiento de destino cuando se ejecute, necesitamos recrear un puntero de tipo void* para almacenar esta dirección.

5. Para evitar que la dirección entrante sea un puntero nulo, debemos usar afirmar para afirmar que la dirección entrante no es un puntero nulo.

2. Implementación de simulación

#include<stdio.h>
#include<assert.h>
//模拟实现memcpy
void* my_memcpy(void* dest, const void* scr, size_t count)
{
	assert(dest && scr);//断言传进来的地址不是空指针
	void* ret = dest;//保存目标起始地址
	while (count--)//拷贝源地址存储的数据
	{
		*(char*)dest = *(char*)scr;
		(char*)dest = (char*)dest + 1;
		(char*)scr = (char*)scr + 1;
	}
	return ret;//返回目标起始地址
}




//应用模拟实现的函数
int main()
{
	int arr1[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
	int arr2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memcpy(arr2, arr1, 24);//拷贝6个字节的数据
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

resultado de la operación:

En tercer lugar, la introducción de la función memmove.

1. Declaración de función

void * memmove ( void * destino, const void * origen, size_t num );  

2. ¿Por qué hay una función memmove?

¿Por qué hay una función memmove? Esto también comienza con la función memcpy anterior. Debido a que la función memcpy no puede copiar los datos en una matriz a sí misma (es decir, los datos de destino son ellos mismos, los datos de origen también son ellos mismos, pero los datos de diferentes ubicaciones en una matriz se copian a otra ubicación), si copia como Se producirán estas copias superpuestas, lo que dará como resultado resultados que no son los que esperábamos.

Como este código:

//应用模拟实现的memcpy函数
int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memcpy(arr + 2, arr, 24);//预期出现结果为1 2 1 2 3 4 5 6 9 10
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//实际出现结果
	}
	return 0;
}

resultado de la operación:

 Razones por las que los resultados esperados y reales pueden diferir:

La razón de este resultado es que se producen copias superpuestas cuando la función memcpy copia sus propios datos en diferentes ubicaciones de sí misma. La dirección de inicio de los datos de origen es arr y la dirección de inicio de los datos de destino es arr + 2. Cuando ingresamos a la función memcpy, primero copiamos los datos en arr a arr + 2 y copiamos los datos en arr + 1 Los datos se copian en arr + 3. Cuando queremos copiar los datos en arr + 2 a arr + 4 , encontramos que los datos en arr + 2 han sido reemplazados por los datos en arr (1) , por lo que podemos solo copiar 1 a arr + 4. Cuando queremos copiar los datos en arr + 3 a arr + 5 , encontramos que los datos en arr + 3 ya han sido reemplazados por arr + 1. data (2) , entonces podemos solo copie 2 a arr + 5 , repitiendo asíCopia superpuesta , los datos copiados siempre son 1/2/1/2/1/2, hasta que se copia el número de bytes que queremos copiar.

Entonces, para copiar nuestros propios datos en diferentes ubicaciones, necesitamos usar la función memmove para implementarla.La función memmove se creó para resolver el problema anterior.

3. Funciones y precauciones

  • La diferencia entre memmove y memcpy es que el bloque de memoria de origen y el bloque de memoria de destino procesados ​​por la función memmove pueden superponerse.
  • Si el espacio de origen y el espacio de destino se superponen, debe usar la función memmove para solucionarlo.

4. Uso de funciones

#include<stdio.h>
#include<string.h>//使用memmove函数时记得引用它的头文件
int main()                  
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	memmove(arr + 2, arr, 24);//预期出现结果为1 2 1 2 3 4 5 6 9 10
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//实际出现结果
	}
	return 0;
}

 Esta vez encontramos que el resultado esperado copiado con la función memmove es el mismo que el resultado real Hablemos de la implementación de simulación de la función memmove.

Cuarto, simule la implementación de la función memmove

1. Análisis de simulación

1. El método para pasar la dirección a la función y la función que recibe la dirección es el mismo que la función memcpy anterior. La función memcpy debe prestar atención a la función memmove. No se repetirá aquí, jeje.

2. Otro punto a tener en cuenta sobre la función memmove es que se necesita analizar cómo copiarla para que no se superponga, el siguiente es un diagrama:

Caso 1: dest es menor o igual que la dirección de src

Copie de adelante hacia atrás como se muestra a continuación para que no haya superposición.

 Caso 2: La dirección de destino es mayor que scr

Copie de atrás hacia adelante como se muestra a continuación para que no haya superposición.

 2. Implementación de simulación

#include<stdio.h>
#include<assert.h>
//模拟实现memmove
void* my_memmove(void* dest, const void* scr, size_t count)
{
	assert(dest && scr);//断言传进来的地址不是空指针
	void* ret = dest; //保存目标起始地址
	if (dest <= scr)//从前往后拷贝
	{
		while (count--)
		{
			*(char*)dest = *(char*)scr;
			(char*)dest = (char*)dest + 1;
			(char*)scr = (char*)scr + 1;
		}
	}
	else//从后往前拷贝
	{
		while (count--)
		{
			*((char*)dest + count) = *((char*)scr + count);
		}
	}
	return ret;
}





//应用模拟实现的函数
int main()                  
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memmove(arr + 2, arr, 24);//预期出现结果为1 2 1 2 3 4 5 6 9 10
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//实际出现结果
	}
	return 0;
}

  resultado de la operación


Resumir

Este es todo el contenido de hoy. Si te parece útil, no olvides darle me gusta y seguir. Gracias por tu apoyo. Finalmente, deseo que los estudiantes graduados puedan bajar a tierra y que los estudiantes que están buscando trabajo puedan ingresar. Dachang.

Supongo que te gusta

Origin blog.csdn.net/qq_64042727/article/details/123714965
Recomendado
Clasificación