Newsgroup: it.comp.lang.c
Titolo: puntatori a strutture composte da puntatori ad altre strutture...sembra una telenovela.... : )

Ciao a tutti e grazie per l'attenzione.
Nella seguente funzione, uso un puntatore ad una struttura che contiene a
sua volta un puntantore ad un'altra struttura.
Ma il compilatore non vuole saperne di accettare la sintassi
strut1->strutt2->membro...come mai?
ho provato strutt->1.strutt2.membro e il compilatore non da errori, ma poi
ovviamente non si ha il passaggio dei dati dalla copia della struttura
creata per la funzione alla struttura vera e propria...HELP!
Grazie in anticipo.
Dome.
typedef struct{
        char nome[20];
        float *voti;
        int  numvoti;
} materia;
typedef struct{
        materia *materie;
        int nmaterie;
        int anno;
        char nome[20];
        char cognome[20];
        char scuola[20];
} pagella;
int InserisciVoto(float voto, pagella *p, int imat)
{
 int ctrl;
 p->materie[imat].numvoti++;
 p->materie[imat].voti = realloc(p->materie[imat].voti,
p->materie[imat].numvoti);
 if (p->materie == NULL)
 {
  printf("Errore nel collocamento del voto\n");
  return (1);
 }
 p->materie[imat].voti[p->materie[imat].numvoti] = voto;
 return (0);
}

creata per la funzione alla struttura vera e propria...HELP!
Scusa, ma non capisco perche' complicarsi la vita con i puntatori,
quando il numero di dati da considerare e' piuttosto ristretto :
/***************
 * 
 * pagella.c
 *
 * Andrea Laforgia
 * 14/11/2000
 *
 ***************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
                  char Nome[50] ;
                  char Cognome[50] ;
                  char Scuola[50] ;
               } TStudente, *PStudente ;
typedef struct {
                  char   Nome[50] ;
                  float  Voti[100] ;
                  int    NumVoti ;
               } TMateria, *PMateria ;
typedef struct {
                 TMateria  Materie[20] ;
                 int       NumMaterie ;
                 int       Anno ;
                 TStudente Studente ;
               } TPagella, *PPagella ;
void InserisciVoto( PMateria P, const float Voto )
{
     if ( P )
     {
        P->Voti[P->NumVoti++] = Voto ;
     }
}
void InserisciMateria( PPagella P, const TMateria Materia )
{
     if ( P )
     {
        P->Materie[P->NumMaterie++] = Materia ;
     }
}
TMateria NuovaMateria( const char *Nome )
{
         PMateria P = malloc( sizeof( TMateria ) ) ;
         if ( P )
         {
            strcpy( P->Nome, Nome ) ;
            P->NumVoti = 0 ;
            return *P ;
         }
}
TPagella NuovaPagella( const TStudente S, const int Anno )
{
         PPagella P = malloc( sizeof( TPagella ) ) ;
         if ( P )
         {
            P->NumMaterie = 0 ;
            P->Anno = Anno ;
            P->Studente = S ;
            return *P ;
         }
}
TStudente NuovoStudente( const char* Nome,
                         const char* Cognome,
                         const char* Scuola )
{
          PStudente P = malloc( sizeof( TStudente ) ) ;
          if ( P )
          {
             strcpy( P->Nome, Nome ) ;
             strcpy( P->Cognome, Cognome ) ;
             strcpy( P->Scuola, Scuola ) ;
             return *P ;
          }
}
void PubblicaPagella( const TPagella P )
{
     int i ;
     printf( "%s\n", P.Studente.Scuola ) ;
     printf( "Anno scolastico         : %d\n", P.Anno ) ;
     printf( "Pagella per lo studente : " ) ;
     printf( "%s %s\n\n", P.Studente.Cognome, P.Studente.Nome ) ;
     printf( "Materie e voti relativi :\n\n" ) ;
     for ( i = 0 ; i < P.NumMaterie ; i++ )
     {
         int j ;
         printf( "[%s]\n", P.Materie[i].Nome ) ;
         for ( j = 0 ; j < P.Materie[i].NumVoti ; j++ )
         {
             printf( "\t%.0f\n", P.Materie[i].Voti[j] ) ;
         }
         printf( "\n" ) ;
     }
}
int main()
{
    TPagella MiaPagella ;
    TMateria Materia ;
    TStudente MioStudente ;
    MioStudente = NuovoStudente( "Andrea",
                                 "Laforgia",
                                 "Universita' degli Studi di Bari" ) ;
    MiaPagella = NuovaPagella( MioStudente, 2000 ) ;
    Materia = NuovaMateria( "Programmazione" ) ;
    InserisciVoto( &Materia, 3 ) ;
    InserisciVoto( &Materia, 1 ) ;
    InserisciVoto( &Materia, 2 ) ;
    InserisciMateria( &MiaPagella, Materia ) ;
    Materia = NuovaMateria( "Laboratorio Programmazione" ) ;
    InserisciVoto( &Materia, 4 ) ;
    InserisciVoto( &Materia, 2 ) ;
    InserisciVoto( &Materia, 1 ) ;
    InserisciMateria( &MiaPagella, Materia ) ;
    PubblicaPagella( MiaPagella ) ;
    return 0 ;
}

 }
Pero':
1) se la malloc() fallisce, il valore ritornato e' ... ?
2) hai fatto una malloc() senza fare la corrispondente free(), e in 
   piu' hai perso ogni riferimento all'area di memoria allocata.
Ti consiglio di riguardare quello che scrivi prima di postarlo.
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

Ti consiglio di riguardare quello che scrivi prima di postarlo.
Rilassati Foco, rilassati.
Il mio programma e' stato scritto come esempio (senza alcun fine
commerciale) e quindi privo dei controlli di sicurezza necessari.
--
Andrea Laforgia (ICQ 87230455)
"programmatori si nasce, non si diventa".

p->materie[imat].numvoti);
Attenzione che realloc vuole conoscere il numero di
char e non il numero di elementi. Dovresti probabilmente usare:
  p->materie[imat].voti =
realloc(p->materie[imat].voti,p->materie[imat].numvoti*sizeof(float));
Io sono pero' profondamente contrario a questo uso di realloc
(le ragioni sono molteplici... dalla gestione errori alle
prestazioni).
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 Rilassati Foco, rilassati.
Io sono rilassato, vedi di esserlo pure tu quando posti, e vedrai
che il tempo per una rilettura lo trovi... 8)


che il tempo per una rilettura lo trovi... 8)
Io non ho bisogno di alcuna rilettura.
Vedi di calmarti.
Se hai suggerimenti, correzioni, modifiche, perche' non le posti,
invece di sparare a zero ?
E' noto che hai l'abitudine di mangiare pesante prima di scrivere su
questo gruppo. E' abbastanza penoso vedere che c'e' gente che non
scrive mai per proporre aiuti, ma per criticare gli aiuti degli altri.
Fatti una camomilla, ne guadagneremo di piu' tutti quanti.
Addio.


 scrive mai per proporre aiuti, ma per criticare gli aiuti degli altri.
[ snip ]
Sinceramente, l'unico modo in cui mi spiego quello che hai scritto
è che ti ho punto sul vivo...be' affari tuoi.
Continuerò a segnalare gli errori (tuoi o di altri) nei quali mi
imbatto, perché penso che sia una cosa utile, e il fatto di urtare
l'orgoglio eccessivo di qualcuno non mi tocca minimamente.


[SNIP]
Non voglio dare torto a nessuno... solo una riflessione...
... Capita sovente di spiegare delle cose a della gente che non sa'
programmare... per la carita'... non stupida, ma semplicemente non sa'
fare certe cose... se io gli sparo subito un codice come questo:
if ( (puntatore = malloc(size * sizeof(struct COME_VUOI)) != NULL)
    esegui;
... beh', se gli dovevi spiegare la malloc (o come usare la malloc per
ottenere un risultato X) e questa e' la prima riga di codice che vede
non e' molto didattico:
- prima gli spieghi  puntatore = mallog (dimensione)....
- poi gli dici che la malloc potrebbe tornare null e in tal caso
sarebbe meglio mettere un controllo etc etc.... (riga sopra)
Andrea Laforgia non ha tutti i torti a postare quel il codice come
l'ha postato... tu hai fatto bene a segnalare gli errori... ma
Laforgia avrebbe dovuto aggiungere in calce al documento 2 righe del
tipo:
//START
Ps: Nota che bisorrebbe mettere un controllo sulla malloc perche' se
torna NULL ... etc etc....
Da notere che l'area di memoria andrebbe deallocata prima di perdere
il punattore altrimenti in certi sistemi operativi la memoria non
viene recuperata...
//STOP
Non scrivere codice (ovviamente come tutti i buoni programmatori C)
compatto e corretto... perche' come gia' detto non e' chiaro per uno
che deve imparare... ricorda che tutti siamo partiti ignoranti sul
C... ti ricordi ancora quando non riuscivi a scrivere un programma per
stampare i numeri da 1 a 10 a video? Sara' che ho da poco preso in
mano il Java e mi rendo conto di come sia duro iniziare... sara' che
ho spiegato come scrivere una shell sotto Unix a dei miei compagni da
poco... 
Oki, ho postato ancora la mia idea... le critiche sono accette, ma
prima provate a spiegare qualcosa a qualcuno che ha dubbi basilari
sulla programmazione in un dato linguaggio e poi vedete quanto questo
riesce a capire il vostro bellissimo codice pieno di tutti i
controlli... 
Mox...
... che continua a preferire il grezzo C al Java perche' il C gli fa'
fare tutto quello che vuole:)
... e che continua a scrivere con i puntini di sospensione sparsi
ovunque per il msg :)