Mi e' parso di capire che il programma deve ricevere in input
un insieme di numeri digitati dall'utente, ognuno dei quali
deve essere inserito in testa a una lista; il ciclo degli inserimenti
si deve interrompere quando l'utente digita 0; poi il programma
deve visualizzare la lista.
Se e' cosi', queste sono le mie osservazioni.
Per gestire la lista basta il puntatore di testa list,
non c'e' bisogno di elem.
E la funzione per l'inserimento si chiama cosi':
list = inserisci_testa(list, valore);
in questo modo la funzione riceve in input il valore del puntatore
al primo nodo della lista, crea un nuovo nodo (che deve puntare
all'ex primo, che diventa il secondo) e rende in uscita
l'indirizzo del nuovo primo nodo.
La scansione della lista non si fa con
for(k = 0; k < I; k++)
{
printf("%lf\n", (elem+k)->x);
}
forse hai confuso con il caso in cui si devono percorrere delle struct
poste in un unico blocco di memoria puntato da un solo puntatore
e utilizzando l'aritmetica dei puntatori.
Per le liste di solito si usa un puntatore ausiliario che assume
all'inizio il valore del p. di testa e che poi viene aggiornato
ad ogni nodo, per leggere il prossimo:
curr = list;
finche' (curr != NULL)
ripeti
mostra il dato del nodo puntato da curr
assegna a curr il valore di curr->next
Cosi' non c'e' neanche bisogno di un contatore dei nodi inseriti (I).
Comunque, e' meglio evitare for (int k = 0; ...);
il mio compilatore (gcc) lo rileva come errore.
Penso che invece di while(1==1) sia preferibile:
do
{
leggi il valore v;
se (v != 0) allora metti v in lista;
}
while (v != 0);
Il ciclo while si presta di piu' quando puo' capitare che il blocco
di istruzioni non debba essere eseguito neanche una volta
(cioe' se la condizione e' falsa fin dall'inizio);
do-while si usa quando il blocco di istruzioni del ciclo
deve essere sempre eseguito almeno una volta (come in questo caso,
perche' almeno un numero - 0 se si vuole finire subito - deve
essere messo).
Se il problema chiede, oltre alla visualizzazione della lista,
anche l'estrazione e la visualizzazione dei numeri man mano che vengono
estratti, devi creare una funzione per l'estrazione del valore
contenuto nel nodo di testa:
double togli_da_lista(lista_t **pp)
{
// puntatore temporaneo
lista_t *p_temp;
// puntatore locale alla lista, cosi' e' possibile
// accedere alla lista senza usare la notazione
// per i doppi puntatori
lista_t *p
// valore letto dal primo nodo (quello che deve essere cancellato)
double v;
p = *pp;
se la lista e' vuota, esci dalla funzione senza fare niente;
se la lista ha un solo nodo, assegna a v il dato dell'unico nodo;
dealloca la memoria occupata del nodo, assegna NULL a p,
assegna p a *pp e restituisci v;
se la lista ha piu' di un nodo, assegna a p_temp il puntatore
al secondo nodo (p->next), assegna a v il dato del primo nodo,
dealloca la memoria puntata da p, assegna p_temp a p (che cosi'
puntera' all'ex secondo nodo, ora primo), assegna p a *pp
e restituisci v.
}
Il puntatore alla lista deve essere passato per indirizzo, non per valore,
perche' il suo valore cambia durante l'esecuzione della funzione e questo
cambiamento deve essere comunicato al programma chiamante.
valore = togli_da_lista(&list);
La funzione deve essere chiamata da un ciclo che iteri l'estrazione
fino allo svuotamento della lista.