Skip to content

ft_putptr

Marcos edited this page Oct 6, 2024 · 1 revision

La función ft_putptr se encarga de imprimir una dirección de memoria en formato hexadecimal, con el prefijo 0x para indicar que se trata de una dirección. La dirección se imprime en minúsculas, y se maneja correctamente el caso de un puntero NULL.

Enlace al código original

Implementación

Inclusión de la Cabecera

#include "ft_printf.h"

Se incluye el archivo de cabecera ft_printf.h para acceder a las funciones necesarias, como ft_putchar y ft_putstr.

Función ft_putptr

int ft_putptr(void *ptr)

Parámetros:

  • void *ptr: El puntero que se va a imprimir.

Funcionamiento:

  1. Conversión a unsigned long long: La dirección del puntero se convierte a un número entero sin signo de 64 bits (unsigned long long) para manejar correctamente las direcciones de memoria.
  2. Verificación de puntero NULL: Si el puntero es NULL, la función imprime la cadena (nil) para indicar un puntero nulo.
  3. Impresión del prefijo 0x: Si el puntero no es nulo, la función imprime el prefijo 0x, que es la notación estándar para direcciones en hexadecimal.
  4. Llamada recursiva: Para imprimir la dirección, se utiliza una función recursiva ft_putptr_recursive, que descompone el número en sus componentes hexadecimales.

Función ft_putptr_recursive

static int ft_putptr_recursive(unsigned long long ptr)

Parámetros:

  • unsigned long long ptr: La dirección de memoria que se va a descomponer e imprimir en formato hexadecimal.

Funcionamiento:

  1. Base hexadecimal: Se utiliza la cadena hex_digits = "0123456789abcdef" para obtener los dígitos hexadecimales.
  2. Llamada recursiva: Si el valor de ptr es mayor o igual a 16, la función se llama recursivamente para dividir el número en bloques de 16 (ya que estamos en base 16).
  3. Impresión de dígitos: Si el valor de ptr es menor a 16, se imprime directamente el dígito hexadecimal correspondiente utilizando ft_putchar.

Código Comentado

#include "ft_printf.h"

/*
 * Esta función imprime una dirección de memoria en formato hexadecimal.
 * Si el puntero es NULL, imprime "(nil)".
 */

int	ft_putptr(void *ptr)
{
	int					count;
	unsigned long long	ptr_val;

    // Inicializamos el contador a 0
	count = 0;
    
    // Convertimos el puntero a un valor numérico de 64 bits
	ptr_val = (unsigned long long)ptr;
    
    // Si el puntero es NULL, imprimimos "(nil)"
	if (!ptr)
		return (ft_putstr("(nil)"));

    // Imprimimos el prefijo "0x"
	count += ft_putstr("0x");

    // Llamamos a la función recursiva para imprimir la dirección en hexadecimal
	count += ft_putptr_recursive(ptr_val);

    // Retornamos el número total de caracteres impresos
	return (count);
}

/*
 * Función recursiva para imprimir la dirección en formato hexadecimal.
 */

static int	ft_putptr_recursive(unsigned long long ptr)
{
	int		count;
	char	*hex_digits;

    // Inicializamos el contador a 0
	count = 0;

    // Definimos los dígitos hexadecimales
	hex_digits = "0123456789abcdef";

    // Si el número es mayor o igual a 16, seguimos descomponiéndolo
	if (ptr >= 16)
	{
        // Llamada recursiva para la parte alta del número
		count += ft_putptr_recursive(ptr / 16);
        // Llamada recursiva para la parte baja del número
		count += ft_putptr_recursive(ptr % 16);
	}
	else
	{
        // Si es menor a 16, imprimimos el dígito correspondiente
		count += ft_putchar(hex_digits[ptr]);
	}

    // Retornamos el número total de caracteres impresos
	return (count);
}

Explicación Paso a Paso de la Recursión

Supongamos que tenemos el siguiente ejemplo:

ft_putptr((void *)123456);  // Queremos imprimir la dirección 123456 en hexadecimal

El proceso sería el siguiente:

  1. Primera llamada a ft_putptr_recursive(123456):

    • El valor de ptr es mayor o igual a 16, por lo que se llama recursivamente.
    • 123456 / 16 = 7716 (parte alta), 123456 % 16 = 0 (parte baja).
    • Se llama a ft_putptr_recursive(7716) y luego a ft_putptr_recursive(0).
  2. Segunda llamada a ft_putptr_recursive(7716):

    • El valor de ptr es mayor o igual a 16, por lo que se llama recursivamente.
    • 7716 / 16 = 482 (parte alta), 7716 % 16 = 4 (parte baja).
    • Se llama a ft_putptr_recursive(482) y luego a ft_putptr_recursive(4).
  3. Tercera llamada a ft_putptr_recursive(482):

    • El valor de ptr es mayor o igual a 16, por lo que se llama recursivamente.
    • 482 / 16 = 30 (parte alta), 482 % 16 = 2 (parte baja).
    • Se llama a ft_putptr_recursive(30) y luego a ft_putptr_recursive(2).
  4. Cuarta llamada a ft_putptr_recursive(30):

    • El valor de ptr es mayor o igual a 16, por lo que se llama recursivamente.
    • 30 / 16 = 1 (parte alta), 30 % 16 = 14 (parte baja).
    • Se llama a ft_putptr_recursive(1) y luego a ft_putptr_recursive(14).
  5. Quinta llamada a ft_putptr_recursive(1):

    • El valor de ptr es menor a 16, por lo que se imprime directamente.
    • Llamamos a ft_putchar('1').
  6. Sexta llamada a ft_putptr_recursive(14):

    • El valor de ptr es menor a 16, por lo que se imprime directamente.
    • Llamamos a ft_putchar('e').
  7. Finalmente: Se imprimen 1, e, 4, y 0 en ese orden, formando la cadena "1e40".

Clone this wiki locally