Menu
Coddy logo textTech

El puntero 'Self'

Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 7 de 61.

En lenguajes orientados a objetos como Python o Java, cuando llamas a object.method(), el lenguaje pasa automáticamente el objeto mismo al método. En C, debemos hacer esto manualmente pasando un puntero a la estructura como primer argumento.

Este puntero se denomina convencionalmente self (tomado de Python) o this (de C++). Le da a la función acceso a los datos de la estructura para que pueda leerlos o modificarlos:

typedef struct {
    int health;
} Player;

void player_take_damage(Player *self, int amount) {
    self->health -= amount;
}

El puntero self es lo que hace que la función actúe como un método; sabe cuál jugador modificar. Sin él, la función no tendría forma de acceder a la instancia específica del struct. Al llamar a esta función, pasas la dirección de tu struct:

Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ahora es 75

Usar un puntero (en lugar de pasar el struct directamente) es esencial para la modificación. Si pasaras el struct por valor, la función recibiría una copia y cualquier cambio se perdería cuando la función retorne. El puntero asegura que los cambios persistan en el struct original.

challenge icon

Desafío

Fácil

Vamos a construir un módulo Timer que rastrea los segundos transcurridos. Practicarás el uso del patrón de puntero "self" para modificar el estado interno de un struct a través de funciones que actúan como métodos.

Crearás tres archivos:

  • timer.h: Declara un struct Timer con un único miembro int seconds. También declara dos funciones: timer_tick (toma un puntero a Timer y añade un número especificado de segundos) y timer_reset (toma un puntero a Timer y vuelve a poner los segundos a cero). Usa protectores de inclusión (include guards) con el símbolo TIMER_H.
  • timer.c: Implementa ambas funciones. La función timer_tick debe aceptar un Timer *self y un int amount, luego añadir la cantidad a los segundos del temporizador. La función timer_reset debe aceptar un Timer *self y establecer sus segundos a cero.
  • main.c: Crea un Timer, realiza operaciones sobre él y muestra los resultados.

Recibirás dos entradas enteras: los segundos iniciales para tu temporizador y la cantidad a añadir mediante el tick.

En tu archivo principal:

  1. Inicializa un Timer con el valor de segundos iniciales
  2. Llama a timer_tick para añadir la cantidad especificada
  3. Imprime los segundos actuales
  4. Llama a timer_reset para reiniciar el temporizador
  5. Imprime los segundos de nuevo (debería ser 0)

Imprime los resultados en este formato:

After tick: {seconds}
After reset: {seconds}

Por ejemplo, con un valor inicial de 30 y añadiendo 15 segundos, la salida sería:

After tick: 45
After reset: 0

Hoja de referencia

En C, las funciones que operan sobre structs necesitan acceso explícito a la instancia del struct a través de un parámetro de puntero, convencionalmente llamado self o this:

typedef struct {
    int health;
} Player;

void player_take_damage(Player *self, int amount) {
    self->health -= amount;
}

El puntero self permite que la función acceda y modifique los datos del struct. Al llamar a tales funciones, pase la dirección de su struct:

Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ahora es 75

El uso de un puntero es esencial para la modificación; pasar por valor crearía una copia y los cambios se perderían cuando la función retorne. El puntero asegura que los cambios persistan en el struct original.

Pruébalo tú mismo

#include <stdio.h>
#include "timer.h"

int main() {
    int initial_seconds, amount_to_add;
    scanf("%d", &initial_seconds);
    scanf("%d", &amount_to_add);
    
    // TODO: Crear un Timer e inicializarlo con initial_seconds
    
    // TODO: Llamar a timer_tick para añadir amount_to_add segundos
    
    // TODO: Imprimir los segundos actuales en formato: "After tick: {seconds}"
    
    // TODO: Llamar a timer_reset para reiniciar el temporizador
    
    // TODO: Imprimir los segundos de nuevo en formato: "After reset: {seconds}"
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming