Programma in C liste

di il
1 risposte

Programma in C liste

Ciao a tutti, devo fare un programma che crei una lista e inserisca in testa i dati. Premetto che non ho capito bene l'argomento, e non riesco a far funzionare questo programma (deve avere necessariamente le due funzioni che returnano un valore di quel tipo e ne prendano dell'altro indicato.
Il programma che ho fatto io è questo:

#include <stdio.h>
#include <malloc.h>

typedef struct lista{
double x;
struct lista *next;
} lista_t;

double leggi_new_value(void);
lista_t *inserisci_testa(lista_t *punt, double v);

int main(void){
lista_t *list=NULL, *elem;
double valore;
int I = 0;

while(1==1){
valore = leggi_new_value();
if(valore==0)
break;
elem = inserisci_testa(list, valore);
I++;
}

for(int k = 0; k < I;k++){
printf("%lf\n",(elem+k)->x);
}
return 0;
}

double leggi_new_value(void){
double valore;
printf("Inserisci un valore :3");
scanf("%lf",&valore);

return valore;
}

lista_t *inserisci_testa(lista_t *punt, double v){
lista_t *elem;
elem = malloc(sizeof(lista_t));
elem->x = v;
elem->next = punt;

return elem;
}

1 Risposte

  • Re: Programma in C liste

    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.
Devi accedere o registrarti per scrivere nel forum
1 risposte