[C] Domanda sulle liste

Atem1
Salve ragazzi avrei una domanda sulle liste.

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
claudio862
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:

int *a = 0;
sizeof(int);
sizeof(*a);
sizeof(1 / 0);
sizeof(*a / 0);

Atem1
Ah ok ti ringrazio ma non capisco la divisione per zero delle ultime 2 righe di codice che hai scritto.

Atem1
E poi avrei un'altra domanda.

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è...

claudio862
"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".

Atem1
"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

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.