Newsgroup: it.comp.lang.c
Titolo: potenzialità

ciao a tutti,
frequento da quest'anno ingegneria informatica e ho cominciato a studiare C.
Mi piacerebbe però sapere quali sono le sue potenzialità.
Quale è il livello dei programmi che è possibile compilare in C?
Rispetto a java o c++ è più o meno potente (o serve a fare cose differenti)?

 Rispetto a java o c++ è più o meno potente (o serve a fare cose differenti)?
Definisci potente. 
Ciao,
-- 
         (__)	      | Nicholas Wieland	    |    -     ------------
	 (oo)	      | 
nicholas...@yahoo.it
   |    -    | There's no |
   /------\/ 	      | Debian GNU/Linux / Mac OS X |    -    | place like |
  / |    ||  	       -----------------------------     -    | *GNOME(2)* |
 *  /\---/\           ...."Have you mooed today?"....    -     ------------

Cendo wrote:

In C puoi fare qualsiasi programma che possa essere implementato in 
linguaggio macchina... e se in C non puoi ti resta sempre la possibilita' 
di inserire direttamente l'ASM :)
Qualsiasi cosa che implementi in C++ o java lo puio fare in C (ovviamente il 
linguaggio e' di un livello piu' basso, quindi in linea di massima devi 
scrivere in piu' codice).
Il C non supporta nativamente il paradigma della programmazione a oggetti, 
ma puo' comunque essere implementata (v. GTK o Linux).
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 oggetti, ma puo' comunque essere implementata (v. GTK o Linux).
Questa cosa mi ha sempre incuriosito, ma non ho mai capito come
č attuabile.
Chi mi fa un esempio semplice di programmazione a oggetti in C?
Grazie
--
Gerolamo

Chi mi fa un esempio semplice di programmazione a oggetti in C?
Io per un po' di tempo ho programmato a oggetti in C
utilizzando dei semplici puntatori a funzione inseriti
in strutture, ovvero utilizzando un livello di indirezione
in meno rispetto alla tecnica VMT normalmente utilizzata
dai compilatori C++. Per farti un esempio... immagina
un programma di disegno in cui esistono gli oggetti
"Shape" generici che prevedono
  - un colore
  - un layer
  - distruttore
  - creatore di copia
  - capacita' di disegno
  - funzione di traslazione
  - funzione di rotazione
  ...
Esempi concreti di questo oggetto "Shape" potrebbero
essere un oggetto "Circle", un oggetto "Polygon",
un oggetto "Rectangle" ... e cosi' via.
Un approccio potrebbe essere...
  typedef struct SHAPE
  {
    /**** Attributi ****/
    int type;          /* ID tipo shape */
    int color;         /* Colore */
    int layer;         /* Layer */
    Shape *prev,*next; /* Link lista di tutte le shape
                          presenti sul disegno */
    /**** Metodi ****/
    void (*destroy)(Shape *this);
    Shape *(*clone)(Shape *this);
    void (*draw)(Shape *this);
    void (*xlate)(Shape *this,double dx,double dy);
    void (*rot)(Shape *this,int cx,int cy,double angle);
    ...
  } Shape;
  // Semplificazione sintassi
  void destroy(Shape *s) { s->destroy(s); }
  Shape *clone(Shape *s) { return s->clone(s); }
  void xlate(Shape *x,double x,double y) { s->xlate(s,x,y); }
  ...
Un esempio di istanza concreta di questa classe
astratta potrebbe essere (nel modulo circle.c)
 
  typedef struct CIRCLE
  {
    Shape s;    /* NB: il primo campo e' di tipo Shape */
    double x,y; /* Centro */
    double r;   /* Raggio */
  } Circle;
  Shape *New_circle(double x,double y,double r)
  {
    /* Trova la memoria */
    Shape *s=malloc(sizeof(Circle));
    if (!s) return 0;
    /* Inizializza ID e parte comune */
    Shape_init(s,CIRCLE_ID);
    /* Imposta puntatori ai metodi */
    s->draw    = Circle_draw;
    s->xlate   = Circle_xlate;
    s->clone   = Circle_clone;
    ...
    /* Imposta attributi */
    s->x=x; s->y=y; s->r=r;
    /* Restituisce l'indirizzo della shape */
    return &s->s;
  }
  Shape *Circle_clone(Shape *s)
  {
    Circle *c=(Circle *)s;
    return New_circle(s->x,s->y,s->r);
  }
  void *Circle_xlate(Shape *s,double dx,double dy)
  {
    Circle *c=(Circle *)s;
    c->x+=dx; c->y+=dy;
  }
  void *Circle_draw(Shape *s)
  {
    Circle *c=(Circle *)s;
    ... codice che disegna il cerchio ...
  }
...
I compilatori C++ normalmente invece usano come ti
dicevo un livello di indirezione in piu'; mettono
tutti i puntatori ai metodi in una tabella e mettono
un puntatore a questa tabella nelle strutture al posto
del campo "type". In altre parole qualcosa del tipo...
   typedef struct SHAPE_VMT
   {
     void (*destroy)(Shape *);
     Shape (*clone)(Shape *);
     void (*draw)(Shape *);
     void (*xlate)(Shape *,double dx,double dy);
     ...
   } Shape_VMT;
e quindi per ogni classe derivata
   Shape_VMT Circle_VMT = {
     Circle_destroy,
     Circle_clone,
     Circle_draw,
     Circle_xlate,
     ...
   };
Le chiamate a metodo in questo caso diventano un
po' piu' complicate...
   void draw(Shape *s) { s->VMT->draw(s); }
ma si evita di avere un puntatore per ogni metodo
in ogni singola istanza di shape (e se ne perde
di conseguenza la flessibilita' aggiuntiva... il
poter modificare un metodo per una particolare
istanza senza dover derivare).
Lavorare a oggetti in C richiede un poco di disciplina
aggiuntiva e l'inventarsi un bel po' di convenzioni,
ma e' comunque fattibilissimo. Con software complesso
il valore aggiunto della semplificazione del progetto
giustifica secondo me la fatica richiesta.
A oggi pero' credo che, se non ci sono altri motivi
molto pressanti, sia un controsenso utilizzare questi
marchingegni se e' possibile utilizzare un compilatore
C++ che automatizza a semplifica tutto questo lavoro
di cesello aumentandone al contempo le prestazioni.
La situazione qualche anno fa era secondo me diversa
(la portabilita' C++ era una barzelletta e i buchi
dei compilatori erano qualcosa all'ordine del giorno)
ma ora per fortuna le cose stanno decisamente meglio.
HTH
Andrea

 ma ora per fortuna le cose stanno decisamente meglio.
Eh, si...
Ma volevo provare l'ebbrezza della programmazione
a oggetti su sistemi embedded :-))
Adesso so come fare...
ciao!
--
Gerolamo


Debian GNU/Linux 3.0r0 (Woody)
Linux Registered User #245762 at 
http://counter.li.org