Punteros

mail@pastecode.io avatar
unknown
plain_text
a year ago
3.8 kB
4
Indexable
Never
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[50]; //Es estatica! si tuviese un * es que es dinamica y hay que reservar memoria con malloc!
    int edad;
}Persona;

typedef struct {
    int alumnos;
    Persona *gente;
}Clase;

void modifica(int *recibido, int valor) { //Al tener la @ de memoria somos capaces de modificar la variable origial.

    //Para editar su contenido editamos lo que hay DENTRO del puntero! (*variable)! Si no, editamos su @! :(
    
    *recibido = valor;

    //NO return!
}

void funcstruct(Clase **clase) { //dereferenciar tantas veces como punteros tengamos!

    (*clase)->alumnos = 7; //Hay que derefedenciar (quitar puntero) SIEMPRE que las estructuras sean un puntero se opera con la (->) y no con el (.)
    (*clase[0]).alumnos = 9; //OJO! tenemos espacio reservado SOLO para UNA estructura la [0]!

}

void funcstruct2(Clase *clase) {

    clase->alumnos = 129;
    (*clase).alumnos = 300;

}

void funcgente(Clase **clase) { //hay que dereferenciar dos veces porque tenemos doble puntero!

    (*clase)->gente[0].edad = 24;
    strcpy((*clase)->gente[0].name, "Juanito");

    (*clase)->gente[1].edad = 32;
    strcpy((*clase)->gente[1].name, "Alberto");
    
    //si no hubiesemos reservado espacio, accederiamos con -> en gente en lugar de con [] ((*clase)->gente->edad)

}

void funcgente2(Clase *clase) {

    clase->gente[0].edad = 2000;
    (*clase).gente[1].edad = 5000;
}

int main() {

    Clase *prog;

    //Un puntero = * y es una direccion de memoria
    int *puntero;
    int numero = 7;
    //Si le hacemos un malloc, estamos reservando memoria para x variables del mismo que el puntero. El puntero apunta a la primera. [0]. NULL!!
    //* es para acceder al contenido. Si NO hay asterisco estamos modificando la @ de memoria del puntero.

    puntero = &numero;

    printf("Direccion de memoria del puntero: %p\n", &puntero);
    printf("Direccion de memoria de variable: %p\n", &numero);
    printf("Direccion de memoria del contenido del puntero: %p\n", &(*puntero));

    printf("Contenido de puntero: %d\n", *puntero);
    printf("Contenido de variable: %d\n", numero);

    //Paso por referencia. Pasar la DIRECCION DE MEMORIA de la variable ORIGINAL que está en el main.
    //Si no pasamos por referencia. Al llamar a una funcion se crea una COPIA!
    //Util para modificar vatriables, estructuras, lalala... desde funciones y no tener que retornarlas.

    modifica(&numero, 1024); //LE MANDO LA @ de memoria!! :)
    printf("Modificado: %d\n", numero);

    modifica(puntero, 30);
    printf("Modificado puntero: %d\n", *puntero);

    //En una struct el mismo nombre de una struct ya es un puntero y si lo declaramos como puntero tenemos doble puntero. *, **.
    prog = (Clase*) malloc(sizeof(Clase)*1); //hemos reservado espacio para UNA clase!
    funcstruct(&prog); //se lo paso con & si NO esta declarada como puntero (*)
    printf("Alumnos en clase: %d\n", (*prog).alumnos);
    printf("Alumnos en clase: %d\n", prog->alumnos);


    funcstruct2(prog);
    printf("Alumnos en clase: %d\n", (*prog).alumnos);
    printf("Alumnos en clase: %d\n", prog->alumnos);


    prog->gente = (Persona*) malloc(sizeof(Persona)*2); //El 2 tambien puede ser una variable! :)
    funcgente(&prog);
    printf("Alumno 0: %s, edad: %d\n", (*prog).gente[0].name, (*prog).gente[0].edad);
    printf("Alumno 1: %s, edad: %d\n", (*prog).gente[1].name, (*prog).gente[1].edad);

    //Para dereferenciar podemos hacerlo con -> o [x] (accediendo al contenido).

    funcgente2(prog);
    printf("Alumno 0: %s, edad: %d\n", (*prog).gente[0].name, (*prog).gente[0].edad);
    printf("Alumno 1: %s, edad: %d\n", (*prog).gente[1].name, (*prog).gente[1].edad);

    return 0;
}