PDA

Visualizza la versione completa : [C] insert in lista concatenata


ant_alt
25-01-2009, 04:00
#include<stdio.h>
#include<stdlib.h>
typedef struct nodo *lista;
typedef struct nodo {
int val;
nodo* next;
} Nodo;


lista insert(lista *L, int valore){
Nodo *corrente;
Nodo *precedente;
Nodo *nuovo;
nuovo=malloc(sizeof(Nodo));
if(nuovo==NULL){
printf("mem esaurita");
return NULL;}
nuovo->val=valore;
nuovo->next=NULL;

corrente = *L;
precedente = NULL;

while(corrente->next!=NULL && valore<corrente->val){
precedente=corrente;
corrente=corrente->next;
}
if(precedente==NULL){
nuovo=*L;
nuovo->next==NULL;
}
else{
nuovo->next=corrente;
precedente->next=nuovo;
}
return *L;
}

int main (){
lista concat = NULL;
int val;
printf("inserisci valore nodo, 0 termina:");
while(scanf("%d", &val)!=0){
insert(&concat, val);
printf("inserisci valore nodo:");
}
system ("PAUSE");
return 0;
}


l'errore (riga 14, la riga della malloc)
In function `nodo* insert(nodo**, int)':
invalid conversion from `void*' to `Nodo*'


edit: ho provato a fare il cast sulla malloc, quindi nuovo=(Nodo*)malloc(sizeof(Nodo));
ora nessun errore di sintassi, ma evidentemente c' qlc errore logico xke il programma crasha

oregon
25-01-2009, 11:13
Prima di tutto, questa

nuovo->next==NULL;

e' sbagliata ...

Comunque, non si capisce il ragionamento che hai fatto nella insert ... cosa dovrebbe fare la insert esattamente per te?

E infine ... il ciclo della scanf non termina con lo zero (che e' un valore accettato ...)

MrX87
25-01-2009, 11:16
bh prima di tutto, direi che inutile fare 2 typedef:


typedef struct nodo *lista;
typedef struct nodo {
int val;
nodo* next;
} Nodo;

perch poi si rischia di fare un p di confusione, come hai fatto tu in qualche caso: infatti quando richiami la funzione insert, non c' bisogno che passi il puntatore alla testa per riferimento:


insert(&concat, val);

anche perch poi lo ritorni con a funzione stessa (return L)!
poi la malloc, una funzione che ritorna un tipo char*, quindi quando non allochi le stringhe bene fare un cast, come hai fatto tu.
per quanto riguarda il crash, bene in genere quando si inserisce in lista, che sia in testa o coda, si fa sempre in 2 modi: si controlla se il puntatore iniziale NULL, per vedere se il primo inserimento, e si procede in un modo, e poi gli altri si eseguono in un altro modo! poi infine volevo spiegato l'utilizzo di quel while() nella funzione insert?? che ti devi ciclare?!

Samuele_70
25-01-2009, 11:40
Originariamente inviato da oregon
Prima di tutto, questa

nuovo->next==NULL;

e' sbagliata ...

Comunque, non si capisce il ragionamento che hai fatto nella insert ... cosa dovrebbe fare la insert esattamente per te?

E infine ... il ciclo della scanf non termina con lo zero (che e' un valore accettato ...)


Originariamente inviato da MrX87
bh prima di tutto, direi che inutile fare 2 typedef:


typedef struct nodo *lista;
typedef struct nodo {
int val;
nodo* next;
} Nodo;

perch poi si rischia di fare un p di confusione, come hai fatto tu in qualche caso: infatti quando richiami la funzione insert, non c' bisogno che passi il puntatore alla testa per riferimento:


insert(&concat, val);

anche perch poi lo ritorni con a funzione stessa (return L)!

No il procedimento va bene :)
Nodo un nuovo dato di tipo struttura nodo
e lista invece un nuovo dato di tipo puntatore a struttura nodo

Originariamente inviato da MrX87
poi la malloc, una funzione che ritorna un tipo char*, quindi quando non allochi le stringhe bene fare un cast, come hai fatto tu.

Ma no che dici, la malloc restituisce un puntatore a void*

Originariamente inviato da MrX87
per quanto riguarda il crash, bene in genere quando si inserisce in lista, che sia in testa o coda, si fa sempre in 2 modi: si controlla se il puntatore iniziale NULL, per vedere se il primo inserimento, e si procede in un modo, e poi gli altri si eseguono in un altro modo! poi infine volevo spiegato l'utilizzo di quel while() nella funzione insert?? che ti devi ciclare?!
Forse hai letto un p troppo in fretta il codice.

@ant_alt
Avevi solo fatto un p di confusione con i puntatori.


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

typedef struct nodo *lista;

typedef struct nodo
{
int val;
struct nodo *next;
} Nodo;

lista insert(lista *L, int valore)
{
Nodo *corrente;
Nodo *precedente;
Nodo *nuovo;

nuovo = (Nodo*)malloc(sizeof(Nodo));
if(NULL==nuovo)
{
printf("mem esaurita");
return NULL;
}
nuovo->val = valore;
nuovo->next = NULL;

corrente = *L;
precedente = NULL;

while( NULL!=corrente && valore>corrente->val )
{
precedente = corrente;
corrente = corrente->next;
}

if(NULL==precedente)
{
nuovo->next = *L;
*L = nuovo;
}
else
{
nuovo->next = corrente;
precedente->next = nuovo;
}
return *L;
}

void visualizza( Nodo *L)
{
while( L )
{
printf("%d,", L->val);
L = L->next;
}
printf("\n\n");
}

int main(void)
{
lista concat = NULL;
int val;
printf("inserisci valore nodo (0 termina) : ");
while(scanf("%d", &val)!=0 && val!=0)
{
insert( &concat, val);
printf("inserisci valore nodo (0 termina) : ");
}

visualizza( concat );

system("PAUSE");
return 0;
}

MrX87
25-01-2009, 12:02
Ma no che dici, la malloc restituisce un puntatore a void*
chiedo venia per gli errori...in effetti sono andato a controllare nel sito dell'ANSI C e la malloc restituisce un void*...poi forse si ho letto un p velocemente...chiedo ancora scusa...per l'unica cosa che non mi convince perch alla funzione insert passi il puntatore a L(che di tipo lista, ovvero gi un puntatore alla struttura nodo) e poi lo ritorni anche??

Samuele_70
25-01-2009, 12:11
Originariamente inviato da MrX87
chiedo venia per gli errori...in effetti sono andato a controllare nel sito dell'ANSI C e la malloc restituisce un void*...poi forse si ho letto un p velocemente...chiedo ancora scusa...per l'unica cosa che non mi convince perch alla funzione insert passi il puntatore a L(che di tipo lista, ovvero gi un puntatore alla struttura nodo) e poi lo ritorni anche??

Si in effetti utile al solo fine di controllare che insert riesca effettivamente ad inserire l'elemento
restituendo la locazione di memoria della testa della lista, oppure NULL in caso di errore. :zizi:

MrX87
25-01-2009, 12:22
Si in effetti utile al solo fine di controllare che insert riesca effettivamente ad inserire l'elemento
restituendo la locazione di memoria della testa della lista, oppure NULL in caso di errore.

bh allora scusa non la stessa cosa se lo passi per valore?? tanto poi lo ritorni sempre, quindi mica perdi la testa della lista?! certo che per devi cambiare il test se l'allocazione del puntatore nuovo va a buon fine, altrimenti torneresti NULL alla testa!


if(nuovo==NULL){
printf("mem esaurita");
exit(0);
}
e fare una chiamata cos:


concat = insert ( concat, valore );

Samuele_70
25-01-2009, 12:28
Si un modo egualmente valido :)

MrX87
25-01-2009, 12:30
okayy...thanks per il chiarimento!

ant_alt
25-01-2009, 14:56
Originariamente inviato da Samuele_70
...


grazie:)

quindi il problema era solo nel while?

while(corrente->next!=NULL && valore<corrente->val)

o mi sfuggito altro?

altra cosa: nella tua funzione visualizza passi come argomento puntatore a nodo (che secondo la mia typedef sarebbe "lista")
perch poi si usa L->val?? cio a me sembra che tu abbia usato due operatori di risoluzione (prima il puntatore a nodo e poi ->)...perch mai funziona? :cry:

Loading