In questo articolo implementeremo la gestione di una pila mediante un array in C.
Nella lezione precedente abbiamo già visto un metodo per la gestione di una pila in C, utilizzando le variabili globali Pila[MAX] e testa di tipo intero. Nell’esempio queste variabili rappresentano l’array e l’indice testa che va da 0 a MAX. Dunque se MAX ad esempio vale 10, testa va da 0 a 10.
La lezione è consultabile al seguente link: pila in C.
In questa lezione impareremo invece a gestire la pila tramite l’uso di funzioni con passaggio di parametri.
Gestione di una pila mediante un array – procedimento
Utilizzeremo dunque queste funzioni di cui elenchiamo i prototipi e le definizioni.
Funzione Push
int Push(int Pila[], int *testa, int n);
Ho costruito questa funzione in modo da prevedere il passaggio dei seguenti parametri:
Pila – il puntatore alla struttura dati (array) che contiene la pila fisicamente;
testa – il puntatore alla testa della pila;
n – l’elemento da inserire.
La funzione restituisce un intero *testa che rappresenta la posizione del puntatore dopo l’inserimento di ciascun valore.
Dunque costruiamo la nostra funzione in questo modo:
Inseriamo l’elemento nella posizione dell’array indicato da *testa. Dopo incrementiamo di uno il valore di *testa:
//inseriamo l’elemento nella posizione indicata da *testa
Pila[*testa]=n;
//incrementiamo di 1 *testa
++*testa;
int Push(int Pila[], int *testa, int n) {
Pila[*testa]=n;
++*testa;
return (*testa);
}
Nel main invochiamo dunque la funzione Push in questo modo:
p=Push(Pila, &p, n);
Dunque in p memorizziamo l’indice ritornato dalla funzione Push.
Funzione Pop
int Pop(int Pila[], int *testa, int n);
La funzione Pop prevede il passaggio dei parametri, Pila, testa ed n.
La funzione restituisce un intero *testa che rappresenta la posizione del puntatore dopo l’eliminazione del valore al top.
Dunque costruiamo la nostra funzione Pop in questo modo:
Decrementiamo di uno il valore di *testa (cioè il puntatore alla testa della pila). Dopo assegniamo il valore dell’elemento in testa alla pila ad n e restituiamo il nuovo puntatore alla pila.
int Pop(int Pila[], int *testa, int n) {
--*testa;
n=Pila[*testa];
printf("\n -> Elemento rimosso %d" , Pila[*testa]);
return (*testa);
}
Pertanto nel main invochiamo la funzione Pop in questo modo:
p=Pop(Pila, &p, n);
Quindi in p memorizziamo l’indice ritornato dalla funzione Pop.
Funzione Print
void Print(int Pila[], int testa);
I parametri passati sono quindi:
Pila – il puntatore alla struttura dati;
testa – l’indice della testa della pila.
La funzione non restituisce pertanto alcun valore.
Dunque costruiamo la nostra funzione Print in questo modo:
void Print(int Pila[], int testa) {
while(testa>=1)
printf("indice %d elemento: %d\n", testa, Pila[--testa]);
}
Con un ciclo while che continua finché l’indice testa è maggiore o uguale a 1, decrementiamo testa e stampiamo il valore corrispondente.
Infatti se ad esempio la pila fosse piena, l’indice testa partirebbe da MAX dove non c’è alcun valore.
Quindi se testa si trova ad esempio in posizione 3, dove non c’è nessun elemento, allora decrementiamo testa di 1 e stampiamo l’elemento corrispondente.
Invochiamo poi la funzione nel programma principale in questo modo:
Print(Pila, p);
Funzione Clear
int Clear(int testa);
Ho costruito questa funzione in modo da prevedere il passaggio come parametro solo dell’indice testa.
Dunque ecco la nostra funzione Clear:
int Clear(int testa) {
printf("\n -> Pila svuotata");
return 0;
}
Facciamo restituire alla funzione semplicemente 0 che rappresenta l’indice della Pila.
Nel main invochiamo dunque la funzione in questo modo:
p=Clear(p);
Ecco dunque il listato completo della gestione di una pila mediante un array:
#include <stdio.h>
#define MAX 10
int menu_scelta(void)
{
int selezione = 0;
do
{
printf("\n" );
printf("\n1 -> Aggiungi un dato" );
printf("\n2 -> Estrai un dato");
printf("\n3 -> Svuota pila");
printf("\n4 -> Stampa pila");
printf("\n5 -> Esci");
printf("\n" );
printf("\nEffettua una scelta: " );
scanf("%d", &selezione );
} while (selezione<1 || selezione>5);
return selezione;
}
int Push(int Pila[], int *testa, int n) {
Pila[*testa]=n;
++*testa;
return (*testa);
}
int Pop(int Pila[], int *testa, int n) {
--*testa;
n=Pila[*testa];
printf("\n -> Elemento rimosso %d" , Pila[*testa]);
return (*testa);
}
int Clear(int testa) {
printf("\n -> Pila svuotata" );
return 0;
}
void Print(int Pila[], int testa) {
while(testa>=1)
printf("indice %d elemento: %d\n", testa, Pila[--testa]);
}
int main(){
int scelta;
int Pila[MAX];
int n, p=0;
while((scelta=menu_scelta())!=5){
switch(scelta){
case 1:
if(p==MAX)
printf("\nPila piena! " );
else {
printf("\nInserisci un dato: " );
scanf("%d", &n);
p=Push(Pila, &p,n);
}
break;
case 2:
p=Pop(Pila, &p, n);
break;
case 3:
p=Clear(p);
break;
case 4:
if(p==0)
printf("\nPila vuota! " );
else
Print(Pila, p);
break;
case 5:
break;
}
}
return 0;
}
Alcuni link utili
Allocazione dinamica della memoria con malloc
Esercitazione sulle struct in C
Realizzare un menù di scelta in C
Come sommare gli elementi della cornice esterna
Ricerca elementi in una matrice