[C] Domanda sulle liste
Salve ragazzi avrei una domanda sulle liste.
Definisco il mio tipo t_lista
Posto
Mi chiedo se le seguenti 2 scritture siano equivalenti:
Scrittura 1:
Scrittura 2
*p sarebbe il contenuto di p, e quindi la dimensione di *p è esattamente la dimensione di t_lista. Giusto?
Anche perchè usando le printf, i 2 valori corrispondono ma non vorrei che fosse solo un caso...
Io quindi penso che le 2 scritture siano equivalenti, qualcuno può confermarmelo?
Non vorrei commettere qualche errore di valuazione...
Grazie mille per l'attenzione
Definisco il mio tipo t_lista
typedef struct elemento { int informazione; struct elemento *link; } t_lista;
Posto
t_lista *p
Mi chiedo se le seguenti 2 scritture siano equivalenti:
Scrittura 1:
p=malloc(sizeof(t_lista));
Scrittura 2
p=malloc(sizeof *p);
*p sarebbe il contenuto di p, e quindi la dimensione di *p è esattamente la dimensione di t_lista. Giusto?
Anche perchè usando le printf, i 2 valori corrispondono ma non vorrei che fosse solo un caso...
Io quindi penso che le 2 scritture siano equivalenti, qualcuno può confermarmelo?
Non vorrei commettere qualche errore di valuazione...
Grazie mille per l'attenzione

Risposte
Sì, sono equivalenti. Spesso si preferisce la seconda alternativa, perché funziona anche se in futuro cambi il tipo di p.
A prima vista sembrerebbe che la seconda non possa funzionare, perché stai dereferenziando il puntatore p prima di avergli assegnato un valore. In realtà l'argomento di sizeof è fittizio, ne viene solo calcolato il tipo e la relativa dimensione, ma l'espressione non viene valutata*. Anzi il compilatore sostituisce direttamente sizeof() con la dimensione (per questo si dice che sizeof è un operatore compile time). Questo sempre, tranne per gli array a lunghezza variabile.
* per esempio queste istruzioni sono equivalenti e valide:
A prima vista sembrerebbe che la seconda non possa funzionare, perché stai dereferenziando il puntatore p prima di avergli assegnato un valore. In realtà l'argomento di sizeof è fittizio, ne viene solo calcolato il tipo e la relativa dimensione, ma l'espressione non viene valutata*. Anzi il compilatore sostituisce direttamente sizeof() con la dimensione (per questo si dice che sizeof è un operatore compile time). Questo sempre, tranne per gli array a lunghezza variabile.
* per esempio queste istruzioni sono equivalenti e valide:
int *a = 0; sizeof(int); sizeof(*a); sizeof(1 / 0); sizeof(*a / 0);
Ah ok ti ringrazio ma non capisco la divisione per zero delle ultime 2 righe di codice che hai scritto.
E poi avrei un'altra domanda.
Io ho fatto un programma con 13 opzioni, e di queste l'unica che non mi funziona è la numero 10
Uso switch(scelta) ed ho:
La procedura e'
Dunque questa procedura dovrebbe essere l'equivalente di quello che chiedo nella seconda opzione.
Cioè io vorrei che il programma mi restituisse in ordine i valori che ho inserito così:
1)
2)
3)
...
i)
...
n)
Invece quello che mi visualizza è questo
1) primo elemento
n+1) n-esimo elemento
...
i+1) i-esimo elemento
...
3) secondo elemento
Me li visualizza tutti, ma in ordine che io non ho chiesto e con dei numeri maggiorati di 1 rispetto alla posizione reale, eccetto per il primo elemento. Il secondo elemento visualizzato è l'ultimo. E non capisco perchè...
typedef struct elemento { char *nome; int voto; struct elemento *next; struct elemento *prev; } t_lista;
void visListaRic(t_lista *l, int i);
Io ho fatto un programma con 13 opzioni, e di queste l'unica che non mi funziona è la numero 10
printf ("\nListe: \n\n"); printf (" 1: Crea nuova lista \n"); printf (" 2: Visualizza lista \n"); printf (" 3: Aggiungi elemento in testa \n"); printf (" 4: Aggiungi elemento in coda \n"); printf (" 5: Elimina elemento \n"); printf (" 6: Scambia di posizione due elementi \n"); printf (" 7: Ordina in ordine decrescente di voto (Insert Sort) \n"); printf (" 8: Visualizza lista in ordine inverso (testa la correttezza di lista->prev) \n"); printf (" 9: Visualizza lista in ordine inverso (con la ricorsione) \n"); printf ("10: Visualizza lista (con la ricorsione) \n"); printf ("11: Aggiungi elemento alla posizione X \n"); printf ("12: Rovescia lista \n"); printf ("13: Conta gli utenti (ricorsione) \n"); printf ("14: Esci \n\n");
Uso switch(scelta) ed ho:
case 10: visListaRic(lista, 1); break;
La procedura e'
void visListaRic(t_lista *lista, int i) { if (lista==NULL) return; printf ("%d) Nome: %s\n",i, lista->nome); printf ("%d) Voto: %d\n\n",i, lista->voto); visListaInvRic(lista->next,++i); }
Dunque questa procedura dovrebbe essere l'equivalente di quello che chiedo nella seconda opzione.
Cioè io vorrei che il programma mi restituisse in ordine i valori che ho inserito così:
1)
2)
3)
...
i)
...
n)
Invece quello che mi visualizza è questo
1) primo elemento
n+1) n-esimo elemento
...
i+1) i-esimo elemento
...
3) secondo elemento
Me li visualizza tutti, ma in ordine che io non ho chiesto e con dei numeri maggiorati di 1 rispetto alla posizione reale, eccetto per il primo elemento. Il secondo elemento visualizzato è l'ultimo. E non capisco perchè...
"Atem":
Ah ok ti ringrazio ma non capisco la divisione per zero delle ultime 2 righe di codice che hai scritto.
Era per enfatizzare il fatto che l'espressione argomento di sizeof non viene valutata (altrimenti avresti un errore a runtime).
void visListaRic(t_lista *lista, int i) { if (lista==NULL) return; printf ("%d) Nome: %s\n",i, lista->nome); printf ("%d) Voto: %d\n\n",i, lista->voto); visListaInvRic(lista->next,++i); }
Chiami "visListaInvRic" invece di chiamare ricorsivamente "visListaRic".
"claudio86":
[quote="Atem"]Ah ok ti ringrazio ma non capisco la divisione per zero delle ultime 2 righe di codice che hai scritto.
Era per enfatizzare il fatto che l'espressione argomento di sizeof non viene valutata (altrimenti avresti un errore a runtime).
void visListaRic(t_lista *lista, int i) { if (lista==NULL) return; printf ("%d) Nome: %s\n",i, lista->nome); printf ("%d) Voto: %d\n\n",i, lista->voto); visListaInvRic(lista->next,++i); }
Chiami "visListaInvRic" invece di chiamare ricorsivamente "visListaRic".[/quote]
Grazie mille, in effetti visto che le 2 procedure erano simili avevo fatto copia-incolla e poi mi ero dimenticato di modificare quel nome e poi faccio fatica a notare errori come questi visto che nella mia testa ero convinto del fatto che ci fosse scritto visListaRic invece di visListaInvRic e quindi anche se l'errore l'avevo davanti agli occhi non riuscivo a vederlo xD