PDA

View Full Version : [C] Problema esercizio C sulle liste


D4rkAng3l
23-05-2005, 18:04
Ciao, tra 8 giorni ho l'esame...inizio a capirci qualcosa ma mi sono impallato con la soluzione di questo esercizio (messa online dal proff ma mi sembra sbagliata ditemi voi) :cry:

L'esercizio chiede di scrivere una funzione che presa in ingresso una lista di char elimini i doppioni e restituisca il puntatore alla lista cos modificata

Il codice della soluzione è questo (è quella del proff...io ho modificato solo la dichiarazione delle variabili e puntatori perchè mi trovo meglioa dichiararli all'inizio del codice anzichè in mezzo al codice...i commenti invece sono i miei, ditemi se ho sbagliato qualcosa):


/* La funzione RipulisciStr() prende in input il puntatore al primo nodo di una
lista di interi, elimina i duplicati ritorna il puntatore al primo nodo della
lista così ripulita, gli elementi della lista hanno il seguente tipo:

typedef struct SList{
char *stringa;
struct SList *next;
} SList;
*/
typedef struct SList{
char *stringa;
struct SList *next;
} SList;

SList *RipulisciStr(SList *L){

SList **pL; /* Dichiaro il doppio puntatore pL che contiene l'indirizzo
della locazione corrente */
SList *elem; // Dichiara il puntatore elem

pL = &L; // Imposta pL con l'indirizzo del primo elemento della lista (?)

while(*pL != NULL){ // Finchè non si è giunti alla fine della lista

elem = *pL; /* Imposta il valore di elem all'indirizzo del nodo
puntato da Pl */

/* Se la funzione TrovaStr restituisce un valore non nullo */
if(TrovaStr(elem->stringa, elem->next)){

*pL = elem->next; /* Imposta il valore puntatoda da pL con
l'indirizzo del campo next puntato da elem*/
free(elem->stringa);
free(elem);
}
/* Se non è stato trovato un doppione nella lista pL contiene
l'indirizzo del prossimo elemento rispetto al campo elem */
else
pL = &(elem->next);
}
return L;
}

/* Funzione ausiliaria che determina se la stringa str è presente o meno nella
lista di stringhe */

short TrovaStr(const char *str, const SList *L){

while(L != NULL && strcmp(str, L->stringa) != NULL)
L = L->next;

return(L != NULL);
}


Ci sono varie cose che non mi tornano:

1) Ma quando faccio pL = &L vuol dire che metto in pL l'indirizzo del puntatore al primo nodo della lista vero? quindi *pL mi dovrebbe dare l'indirizzo del primo nodo....giusto? e **pL che dovrebbe darmi allora?!?!

2) Se trova un doppione libera lo spazio del vettore stringa e poi libera il nodo ma non và a rilinkare i nodi della lista una volta eliminato un nodo...mi pare strano !!!

3) non ho capito bene che restituisce la funzione ausiliaria....

vi prego aiutatemi...ditemi che non sono completamente demente e che in questa soluzione c'è qualcosa che non torna...

71104
23-05-2005, 18:21
premessa: il tuo prof ha un pessimo modo di programmare (è talmente ingenuo da far tenerzza...).

1) Ma quando faccio pL = &L vuol dire che metto in pL l'indirizzo del puntatore al primo nodo della lista vero? quindi *pL mi dovrebbe dare l'indirizzo del primo nodo....giusto? e **pL che dovrebbe darmi allora?!?! il nodo stesso, no?

2) Se trova un doppione libera lo spazio del vettore stringa e poi libera il nodo ma non và a rilinkare i nodi della lista una volta eliminato un nodo...mi pare strano !!! hai ragione: si vede che ti ho addestrato io!!! :D e quello è un errore, ma ce n'è anche un altro!! ;) riesci a trovarlo?

3) non ho capito bene che restituisce la funzione ausiliaria.... ragiona: l'operatore != restituisce un valore booleano, cioè restituisce 0 se le due espressioni sono uguali, 1 se sono diverse; quindi la funzione ausiliaria ti restituisce un valore indicativo del fatto che sia stato trovato o meno un doppione: infatti se il doppione non è stato trovato, con l'iterazione L sarà arrivato alla fine (cioè a NULL), quindi "L != NULL" restituirà 0 e la funzione pure (giustamente la funzione restituisce 0 se non trova il doppione, 1 altrimenti).

vi prego aiutatemi...ditemi che non sono completamente demente e che in questa soluzione c'è qualcosa che non torna... e va bene, questa volta te lo sei meritato: non sei completamente demente (anzi!) e in questa soluzione ci sono molte cose che non tornano (e se mi sbaglio pure io allora ad essere dementi saremo in due: contento? :D); ma ti dirò di più: con un professore così, capisco perfettamente che tu ti lamenti delle difficoltà con il C e con le liste.

D4rkAng3l
23-05-2005, 18:28
premessa: il tuo prof ha un pessimo modo di programmare (è talmente ingenuo da far tenerzza...).

il nodo stesso, no?

hai ragione: si vede che ti ho addestrato io!!! :D e quello è un errore, ma ce n'è anche un altro!! ;) riesci a trovarlo?

ragiona: l'operatore != restituisce un valore booleano, cioè restituisce 0 se le due espressioni sono uguali, 1 se sono diverse; quindi la funzione ausiliaria ti restituisce un valore indicativo del fatto che sia stato trovato o meno un doppione: infatti se il doppione non è stato trovato, con l'iterazione L sarà arrivato alla fine (cioè a NULL), quindi "L != NULL" restituirà 0 e la funzione pure (giustamente la funzione restituisce 0 se non trova il doppione, 1 altrimenti).

e va bene, questa volta te lo sei meritato: non sei completamente demente (anzi!) e in questa soluzione ci sono molte cose che non tornano (e se mi sbaglio pure io allora ad essere dementi saremo in due: contento? :D); ma ti dirò di più: con un professore così, capisco perfettamente che tu ti lamenti delle difficoltà con il C e con le liste.


che intendi che mette il nodo stesso in pL?! scusa ma stò un po' fuso ora, ah grazie mille della tua costante disponibilità...ti venero :)

beppegrillo
23-05-2005, 18:35
premessa: il tuo prof ha un pessimo modo di programmare (è talmente ingenuo da far tenerzza...).

Eh forse sono esempi semplici fatti di proposito. Non capiscono così figuriamoci se volesse complicarli :asd:

D4rkAng3l
23-05-2005, 18:39
Eh forse sono esempi semplici fatti di proposito. Non capiscono così figuriamoci se volesse complicarli :asd:
si vabbè ma che cavolo certe cose sò allucinanti...elimini un nodo dalla lista...devi rilinkare gli altri altrimenti quando vai a fare la scansione sono casini

71104
23-05-2005, 20:17
Eh forse sono esempi semplici fatti di proposito. Non capiscono così figuriamoci se volesse complicarli :asd: non, non hai capito: non mi riferivo alla chiarezza, intendevo dire che il suo prof a programmare è una sega! con quella sedicente "soluzione" in poche righe ha preso tanti di quegli strafalcioni che a pensare a tutti quei poveri studenti in balìa di quel cretino vengono prima i brividi e poi una pena infinita... povero darkangel e poveri i compagni suoi... :D

71104
23-05-2005, 20:22
che intendi che mette il nodo stesso in pL?! scusa ma stò un po' fuso ora, ah grazie mille della tua costante disponibilità...ti venero :) denghiu' ^^ cmq, prendi questo esempio:


typedef _nodo {
//...
} nodo, *pnodo;
.
.
.
nodo n;
pnodo pn = &n;
pnodo *ppn = &pn;
tu hai questo nodo n e un puntatore ad esso che si chiama pn; poi hai anche una variabile ppn che punta a pn; se tu fai il dereferencing di ppn ottieni pn; se fai il dereferencing di pn (cioè *pn) che cosa ottieni? ecco, la stessa cosa la ottieni facendo il doppio dereferencing di ppn, cioé **ppn; quello che ottieni non è un puntatore ad n, ne' è un puntatore a un puntatore ad n: è n stesso, cioè risulta precisamente **ppn == n;

spero di essere stato chiaro. :)