Newsgroup: it.comp.lang.c++
Titolo: Typedef che non mi spiego

Ciao a tutti.
Non mi riesco a spiegare questo typedef:
#include...
int cont;
int livellomax;
typedef int pippo;
enum tordine { pre, in, post };
struct tnodo{
 int x;
 tnodo *ps, *pd;
};
// *** IL SEGUENTE ***
typedef void (*tipo_fai_su_nodo) (tnodo*); // tipo di procedura da passare
come parametro, essa "fa qualcosa" sul nodo;
// definisco un nuovo nome per void, ma cosa serve la parte " (tnodo*) " ?
.......
void fai( tnodo*, tipo_fai_su_nodo, tordine ); //        Non capisco
l'utilizzo di "tipo_fai_su_nodo" in questo prototipo.
void scrivi(tnodo*)
........
int main()
{ tnodo *a1; // radice dell'albero
   ..........
   .........
  cout << endl < <"scrivo albero in ordine di visita infisso" << endl;
   fai( a1, scrivi, in );             // Perchè si usa il nome della
funzione scrivi quà ?
Per correttezza vi posto il programmino completo  nel caso in qui io non sia
stato troppo chiaro.
Grazie a chiunque voglia rispondermi.
Simone
#include <conio.h>
#include <iostream.h>
#include <stdlib.h>
int cont;
int livellomax;
typedef int pippo
enum tordine { pre, in, post };
struct tnodo{ int x;tnodo *ps, *pd; };
typedef void (*tipo_fai_su_nodo) (tnodo*);
// tipo di procedura da passare come parametro,
// essa "fa qualcosa" sul nodo;
void metti( tnodo *&, int );
void scrivi(tnodo*);
void conta(tnodo*);
void fai( tnodo*, tipo_fai_su_nodo, tordine );
void scriviLIV( tnodo* p, int livello );
void at(){ cout<<"tasto"; getch(); };
int main(){
  tnodo *a1; // radice dell'albero
  int dato;
  clrscr();
  a1 = NULL;
  cout<<" ES ALBERI - 1) ALBERO BINARIO ORDINATO" <<endl;
  do{
   cout<<"inserisci numero, 0 per finire";  cin>>dato;
   if(dato==0) break;
   metti( a1, dato );
  }while(1);
  cout<<endl<<"scrivo albero in ordine di visita infisso" <<endl;
   fai( a1, scrivi, in );
  at();
  cout<<endl<<"scrivo albero in ordine di visita prefisso" <<endl;
  fai( a1, scrivi, pre );
  at();
  cout<<endl<<"scrivo albero in ordine di visita postfisso" <<endl;
  fai( a1, scrivi, post );
  at();
  cout<<endl<<"conto i nodi" <<endl;
  cont=0;
  fai( a1, conta, pre );
  cout<<"ho contato "<<cont<<" nodi"<<endl;
  at();
  cout<<endl; livellomax=0;
  scriviLIV(a1,0); // scrivi con visualizzazione livelli ...
  cout<<endl<<" livellomax="<<livellomax<<endl;
  at();
  return 0;
}  // main
void metti( tnodo *& radice, int dato) {
// metti dato nell'albero binario ordinato:
 if(radice==NULL) {
   radice = new tnodo; radice->x=dato;
   radice->ps=NULL; radice->pd=NULL;
 }
  else if ( dato < radice->x )
       metti( radice->ps, dato);
  else metti(radice->pd, dato);
} // metti
void scrivi(tnodo* p) {
  cout<<' '<< p->x<<' ';
}  // scrivi
void conta(tnodo* p) {
   if(p!= NULL) cont++;
}
// typedef void (*tipo_fai_su_nodo) (tnodo*);
// void fai( tnodo*, tipo_fai_su_nodo, tordine );
void fai( tnodo* r, tipo_fai_su_nodo ff, tordine ord){
 if(r==NULL) return; else ;
 if(ord==pre) {
  ff(r);
  fai( r->ps, ff, ord );
  fai( r->pd, ff, ord );
 }
 else if(ord==in) {
  fai( r->ps, ff, ord );
  ff(r);
  fai( r->pd, ff, ord );
 }
 else {
  fai( r->ps, ff, ord );
  fai( r->pd, ff, ord );
  ff(r);
 }
} // fai
void scriviLIV( tnodo* p, int livello ) {
// visita in ordine infisso o simmetrico: scrivi S.A.Sin, Rad, S.A.Des
 if( p!=NULL) {
  livello++;   // ATT: livellomax da inizializzare nel main!
  if (livello > livellomax) livellomax=livello;
  scriviLIV(p->ps, livello);
  // ora scrivi radice, con il suo livello:
   cout<<livello;
   for(int i=1; i<= livello; i++) cout<<"  ";
   cout<<p->x<<endl;
  scriviLIV(p->pd, livello);
 }
} // scriviLIV

 l'utilizzo di "tipo_fai_su_nodo" in questo prototipo.
Ciao Simone,
hai confuso un po' il concetto.
Tu non stai definendo un nuovo nome per void.
Tu stai definendo un puntatore a funzione.
Nel caso specifico il tuo puntatore a funzione si chiamera':
tipo_fai_su_nodo
E questo puntatore puntera' a una funzione che restituisce void,
e avra' come suo unico parametro una variabile di tipo puntatore a tnodo.
Insomma tu hai definito un puntatore a void f(tnodo *)
Quando hai un typedef di quel tipo, il nuovo nome con cui vuoi chiamare il
puntatore a funzione sta dopo il primo tipo che e' il tipo di ritorno, e fra
parentesi dopo l'asterisco.
In generale:
typedef TipoRitornoFunzione (*NuovoNome)(TipoArgomentoFunzione1,
...,TipoArgomentoFunzioneN).
Per una funzione con N parametri.
Per cui la tua funzione fai, vuole come secondo argomento un puntatore a
funzione del tipo che hai definito.
Es:
struct tnodo
{
// vari campi
};
void GetNodo(tnodo *pNodo)
{
// Prende un nodo
}
#define TINSERT 0
typedef void (*tipo_fai_su_nodo) (tnodo*);
void MakeFai()
{
    tnodo *nodo = new(tnodo);
    tipo_fai_su_nodo pFuncNodo = &GetNodo();
    fai(nodo, pFuncNodo, TINSERT);
}
Maurus

  ff(r);
Qui` viene richiamata la funzione che era stata passata come parametro.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Do, or do not. There is no try.

Grazie per le risposte