¿Me podrian explicar como funciana los punteros en una pila con el sgte ejercic?

Iniciado por maicol_962016, 22 Febrero 2016, 21:42 PM

0 Miembros y 1 Visitante están viendo este tema.

maicol_962016

alguien me podría explicar esta forma de usar punteros es que no me queda muy clara y me confundo.

typedef struct nodo{
int valor;
struct nodo *siguiente;
}tiponodo;
typedef tiponodo *pila; //esta es la parte q no me queda tan clara ya q lo q entiendo es que estamos //creando un puntero que va contener direcciones de memoria de la estructura tiponodo que se llama pila y con typedef lo podemos declarar con el nombre //pila;

typedef tiponodo *pnodo;//y en esta linea hacemos lo mismo q lo anterior
void push(pila *pil,int v);
int main(){
pila pil=NULL; //aqui creo q el contenido de este puntero es una direccion nula
push(&pil,5); //aqui creo que estamos enviando la direccion de memoria de pil q es un puntero
push(&pil,8);
push(&pil,10);
return 0
}
void push(pila *pil,int v){//aqui esta parte si no entiendo nada xq se supone q pila ya es un puntero y xq creamos un puntero de tipo puntero y se me hace confuso.

pnodo nuevo=(pnodo)malloc(sizeof(tiponodo));
nuevo->valor=v;
nuevo->siguiente=*pil;
*pil=nuevo;
}

sodark


MAFUS

Es confuso al principio pero debes visualizarlo de esta forma:

Las funciones, al recibir parámetros, reciben copias de los datos. Cuándo reciben un puntero, lo que reciben es una copia del puntero. Jugar con ésto permite al programador poder modificar los valores de una variable externa, como bien sabes, al pasar la referencia de esa variable.

Si miras el código se necesita variar el puntero en sí:
void push(pila *pil, int v) {
  pnodo nuevo = malloc(sizeof(tiponodo));
  nuevo->valor = v;
  nuevo->siguiente = *pil;
  *pil = nuevo;
}


Como puedes ver en la linea 5 el valor de pil, que en realidad es una dirección de memoria, recibe el valor del puntero nuevo. Si no se hubiera usado un puntero a puntero en la llamada a la función, ésta trabajaría con una copia local de la dirección del puntero pil y, al salir del ámbito de la función push, no habría habido cambios en main, con lo que el programa no haría lo que debería hacer.

La forma de trabajar es la misma que si fuera un dato normal:
Por ejemplo una función declarada así
void cambiar_int(int* i);
ya puedes imaginar que se cambiará el contenido del entero i que se le pase con
cambiar_int(un_numero);
Pues de la misma forma puedes esperarte que a la siguiente función
void cambiar_direccion(int** p);
servirá para que puedas cambiar la dirección a la que apunta un puntero que le pases así:
cambiar_direccion(&un_puntero_a_int);
Aunque cuidado, porqué también se puede referir a que se va a pasar una tabla, pero eso ya es otro tema.

furciorifa

Primero que nada te recomiendo leer Understanding and Using pointers in C es de la editorial O'reilly , lo subiría aquí pero son muy especiales a la hora de compartir contenido de este tipo.

lfgmespino

Debería quedar así.


#include <stdio.h>
#include <stdlib.h>

typedef struct nodo{
int valor;
struct nodo *siguiente;
} tiponodo;

typedef tiponodo* pPila; //En pPila se guardará la dirección del primer elemento de la lista (pila)
typedef tiponodo* pNodo; //Se define un nuevo tipo de dato, pNodo, que es un Puntero a una struct nodo (tiponodo)

void push(pPila *ptr, int v);
int  pop(pPila *ptr);

int main() {

pPila *pila = NULL; //Se pone a cero la dirección contenida en pila. Es decir, lista vacía.

push(&pila, 5); //Se pasa la dirección de la pila
push(&pila, 8);
push(&pila, 10);
printf("\n%d", pop(&pila));
printf("\n%d", pop(&pila));
printf("\n%d", pop(&pila));


return 0
}

void push(pPila *ptr, int v){ //Pasamos a la función la dirección de un elemento tipo pila.

pNodo nuevo = (pNodo ) malloc(sizeof(tiponodo)); //Se crea un nuevo nodo
if (nuevo == NULL) exit(1);
nuevo->valor = v;
nuevo->siguiente = *ptr; //Se guarda la dirección del hasta ahora primer elemento de la lista
*ptr = nuevo; //Se anota en pila la dirección de este nuevo nodo, que pasa a ser el primero
}

int  pop(pPila *ptr){ //Pasamos a la función la dirección de un elemento tipo pila.

   pNodo ptrTemp; //Se crea una direccion a tiponodo para poder luego liberar memoria
   int num;

if (*ptr == NULL) printf ("\nPila vacía.");
   else {
ptrTemp = *ptr; //Se guarda la dirección del primer elemento de la pila
num =  ptrTemp->valor;
*ptr = ptrTemp->siguiente; //Pila coge la dirección del siguiente elemento al primero, con lo que primero está listo para eliminar
free(ptrTemp);
       }
       
  return num;     
}


furciorifa

La manera más fácil de visualizar es para modificar int x=3 pasándolo a una función void modifica(int * modificar)   tenemos que pasar por referencia & x entonces lo que quieres modificar es un puntero pero por referencia entonces debes usar un puntero a puntero para poder modificar este