Ciao! premetto che le liste in C non sono una struttura dati nativa, per cui è compito del programmatore scrivere tutte le funzioni relative.
Innanzitutto bisogna conoscere i puntatori: un puntatore è una variabile che contiene un indirizzo di memoria, e viene usato per accedere ai dati a partire dall'area in cui sono memorizzati.
Alcuni puntatori probabilmente li hai già visti ma non sono chiamati così, prendiamo ad esempio una stringa di caratteri
codice:
char stringa[10];
questo codice dichiara un vettore di dieci caratteri, ma allo stesso tempo un puntatore ad un'area di memoria.
La variabile stringa è infatti l'indirizzo del primo carattere, puoi fare una prova per vederlo
codice:
for(i=1;i<10;i++)
stringa[i]='a';
printf ("%s",stringa)
sullo schermo, se tutto va per il verso giusto, oltre alle 10 a previste dovrebbero comparrire un mucchio di segni strani, per il fatto che le funzioni di stampa delle stringhe leggono aree di memoria contigue fino a trovare quella che contiene il carattere NUL ('\0' ), cioè la terminazione delle stringhe.
Ora, come esempio creo un vettore di stringhe
codice:
#include <stdlib> /*serve per le funzioni di gestione della memoria*/
#include <stdio.h>
#include <string.h> /*contiene funzioni per gestire le stringhe*/
int main(){
char buffer[30];
char ** vett; /* doppio puntatore, un doppio puntatore
contiene può essere untilizzato per contenere
un vettore di puntatori*/
int i=0;
vett = (char ** )malloc ( sizeof (char *) * 10 );
/*tanti asterischi, non hanno tutti lo stesso significato
innanzitutto va detto che la malloc restituisce un generico
puntatore, che deve essere adattato alla variabile su cui si
sta lavorand mediante un'operazione detta casting che corrisponde
a scrivere (char **) davanti alla funzione chiamata, così ora il
risultato calza a pennello.
La malloc chiede quanta memoria vogliamo destinare al vettore;
mediante l'operatore sizeof stabilisco la dimensione di un
generico puntatore a caratteri (char *) quindi mi basta
moltiplicare il risultato ottenuto per il numero di stringhe che
desidero immettere nel mio vettore.*/
for (i=0;i<10;i++){
printf ("inserire stringa>>"); /*un prompt per chiarezza*/
gets (buffer); /*prende una stringa da utente e la memorizza
nel buffer che ho definito, aggiungendo il
carattere NUL dopo la stringa immessa*/
vett[i] = (char *) malloc (strlen(buffer)+1 );
/*ecco la parte interessante, innanzitutto la funzione strlen
restituisce la lunghezza di una stringa senza però tenere
conto del "tappo" (il carattere NUL che la termina), quindi
ho dovuto aggiungere un pezzo "a mano" ( il +1) in modo che
la memoria bastasse.
Il risultato di questa operazione è che mi ritrovo con
un'area di memoria della stessa dimensione del dato che
l'utente ha immesso, così non spreco davvero nulla.*/
strcpy(vett[i],buffer); /*questa funzione semplicemente copia
il contenuto di buffer in vett[i]*/
printf ("%s\n", vett[i]); /*stampare per credere*/
exit(0);
}
}
Con questo codice ho creato un vettore di 10 stringhe di lunghezza esattamente uguali a quelle digitate da utente, ma si può fare di meglio.
codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (){
char ** vett ,
* terminazione = "fine",
/*questa è una stringa di caratteri, effettuando
l'assegnazione in fase di dichiarazione, alla stringa
verrà assegnata d'ufficio un'area di memoria sufficiente
a contenere la parola fine ed il carattere NUL*/
buffer [30]='\0';
int i=0;
while (strcmp(buffer,terminazione)!=0){
/*la strcmp confronta due stringhe e restituisce 0 se sono
uguali, altri valori se sono diverse*/
vett = (char ** ) realloc (sizeof (char *));
/*la realloc agginge spazio ad una variabile, per esempio
adesso ho aggiunto alla variabile vett lo spazio necessario
per ospitare un altro puntatore a caratteri*/
printf ("inserire stringa>>"); /*un prompt per chiarezza*/
gets (buffer);
vett[i] = (char *) malloc (strlen(buffer)+1 );
strcpy(vett[i],buffer);
printf ("%s\n", vett[i]);
i++;
}
exit(0);
}
Con questo codice ho creato un vettore a cui aggiungo dinamicamente la memoria necessaria per i nuovi elementi, senza sprecarne neanche una goccia.
Spero di essere stato utile, ciao!