PDA

Visualizza la versione completa : [C] Funzione che non ritorna puntatore a lista


.:DarkSkull:.
08-09-2011, 23:05
Ciao a tutti! Sto facendo un esercizio che mi chiede di codificare un numero tramite una lista, e i nodi di questa lista devono essere i fattori primi del numero ordinati dal più grande al più piccolo. Ho scritto tutto il programma e l'unico problema è che non mi ritorna il puntatore al primo elemento della lista. Vi posto il codice:


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

typedef struct node{
int num;
struct node *next;
}list;

list *ordina(list *);
list *scomposizione(int n, list *);
void stampa_lista(list *);


// Qui è il mio problema
list *scomposizione(int n, list *l)
{
int j;
j = 2;
do
{
list *p = l;
if(n % j == 0)
{
p = malloc(sizeof(list));
p->num = j;
n = n / j;
p = p->next;
}
else
j++;
}
while (n > 1);
return l;
}

// la funzione ordina svolge il suo compito in modo corretto
list *ordina(list *l) {
int k;
if (l && l->next) {
do {
list *punt = l;
k = 0;
while (punt->next) {
list *punt1 = punt;
punt = punt->next;
if ((punt1->num) < (punt->num)) {
int tmp = punt1->num;
punt1->num = punt->num;
punt->num = tmp;
k = 1;
}
}
} while (k != 0);
}
return l;
}

void stampa_lista(list *l)
{
while(l != NULL)
{
printf("%d ", l->num);
l = l->next;
}
printf("\n");
}



int main()
{
int a;
list *l1 = NULL;
printf("Inserisci numerO:\n");
scanf("%d",&a);
scomposizione(a, l1);
ordina(l1);
stampa_lista(l1);
return 0;
}

SancheZ
09-09-2011, 00:15
Ciao a te, andiamo per ordine:

1) la funzione scomposizione() non riuscirà mai a restituire al chiamante il parametro "l1" modificato, in quanto questo viene passato per valore e non per indirizzo. Quindi la tua funzione diventerà: list *scomposizione(int n, list **l) e sarà invocata con scomposizione(a, &l1) dalla funzione main()

2) la funzione scomposizione() per come è scritta non inizializza mai il primo elemento della lista (l'istruzione list *p=l; all'inizio del loop non funziona come forse ti immagini) e, di conseguenza, ogni elemento puntato dalla variabile p viene "perso" subito dopo l'inizializzazione con l'istruzione p=p->next; causando i cosiddetti "memory leaks" (o garbage, se preferisci). Una soluzione può essere la seguente:



list *scomposizione(int n, list **l)
{
int j;
list *p=NULL; // <- puntatore all'elemento corrente
j = 2;
do
{
list *li=NULL; // <- puntatore all'elemento in creazione
if(n % j == 0)
{
// qui alloco e inizializzo un nuovo elemento
li=(list *)malloc(sizeof(list));
li->num=j;
li->next=NULL;
// faccio i calcoli
n=n/j;

// se non esiste, il nuovo elemento diventa il primo elemento della lista...
if (*l==NULL) *l=li;
// ...altrimenti il nuovo elemento diventa l'elemento successivo della lista...
else p->next=li;
// ...e il nuovo elemento è anche l'elemento corrente
p=li;
}
else
j++;
}
while (n > 1);
return *l;
}


Stefano.

.:DarkSkull:.
09-09-2011, 13:42
Grazie mille sei stato chiarissimo! :love:

SancheZ
09-09-2011, 16:38
Per essere più precisi ancora, l'istruzione list *p=NULL; all'inizio della routine non è corretta nel caso in cui si parta con la lista non-vuota, per cui deve diventare list *p=*l;.

Stefano.

Loading