PROGRAMMAZIONE A OGGETTI 2001-2002

10-12-2001

 

OPERATORI E PASSAGGIO PARAMETRI

VISIBILITA' DELLE VARIABILI

TYPEDEF

DATI STRUTTURATI

STRUTTURE E FUNZIONI

INCLUSIONE DI HEADER FILES

 


 

OPERATORI E PASSAGGIO PARAMETRI

Un puntatore è una variabile il cui contenuto è l'indirizzo di una cella di memoria. Per definire un puntatore si usa la sintassi:

tipo *pi;

Dove tipo è il tipo del contenuto della cella di memoria puntata (se tipo=int avrò un puntatore a interi, se tipo=char avrò un puntatore a caratteri).

Per accedere al contenuto della cella di memoria puntata si usa l'operatore di dereferenziazione *

J = *pi;

Se J è di tipo int viene inizializzata al valore contenuto nella cella puntata da pi.

Per ottenere l'indirizzo di una cella di memoria associata ad una variabile si usa l'operatore di indirizzo &:

pi = &i;

In pi viene messo l'indirizzo della variabile i che è di tipo int.

Ci sono tre metodi per passare i parametri ad una funzione: by value by address o by reference. Il passaggio by value viene effettuato in questo modo:

int f(int i);

Il valore passato alla funzione viene copiato nella variabile locale i della funzione. Il passaggio by address è il seguente:

int f(int *pi);

Si può passare alla funzione o un puntatore o un indirizzo ottenuto con l'operatore &.Il passaggio by reference è il seguente:

int f(int& pi);

Passando una variabile alla funzione l'operatore & fa si che in pi (puntatore) venga copiato l'indirizzo della variabile. Pi diventa quindi un puntatore alla variabile passata.

HOME


 

VISIBILITA' DELLE VARIABILI

In C++ si può definire una variabile in ogni punto del programma.

Se una variabile non è definita dentro nessuna funzione allora è una variabile globale che è visibile in ogni punto del programma (non è buona cosa definire variabili globali). Una variabile locale è definita in una funzione ed ha significato solo in quella funzione. Se una variabile locale ha lo stesso nome di una globale, il compilatore dà la precedenza alla variabile locale (regole di scope). Due variabili locali definite in due funzioni diverse e con lo stesso nome sono comunque due variabili diverse. Le variabili locali vengono eliminate alla chiusura della funzione.

extern "variabile_ globale";

La variabile globale così definita viene resa visibile a tutti i file che compongono il file sorgente.

static "variabile_globale";

La variabile globale questa volta è visibile solo nel file in cui è definita.

static "variabile_locale";

Una variabile locale definita in questo modo mantiene il valore che le è associato anche dopo la chiusura della funzione, pronto per essere riutilizzato una volta richiamata la funzione.

HOME


 

TYPEDEF

Si può rinominare un tipo già esistente con l'istruzione:

typedef oldname newname;

Questa operazione è molto utile quando si utilizzano le strutture.

HOME


 

DATI STRUTTURATI

I dati strutturati servono ad organizzare i dati in memoria in strutture comuni di facile accesso. Ci sono tre modi per strutturare i dati:

con un array: una successione di elementi tutti dello stesso tipo memorizzati in memoria in locazioni consecutive. Si accede ai vari elementi con un indice.

con una union: è una zona di memoria che può essere utilizzata con diversi tipi di dato diversi e diversi nomi.

con una struct: diversi tipi di dato sono memorizzati sotto lo stesso nome (il nome della struttura). Inoltre ogni tipo di dato è individuato da un nome (nome del campo della struct) ed è così accessibile. Ecco un esempio di struttura:

 

struct wp_char {

char wp_cval;

int wp_font;

int wp_size;

}

 

Il nome della struct è wp_char e al suo interno sono definiti tre campi. Una volta definita una struct la si può utilizzare come se fosse un nuovo tipo di dato. Si possono definire degli elementi di tipo "struct wp_char":

struct wp_char a1,a2;

In C++ viene automaticamente ridefinito il tipo "struct wp_char" come "wp_char", quindi la precedente dichiarazione può essere riscritta:

wp_char a1,a2;

Il nome di un elemento di tipo struct è un puntatore al primo elemento della struttura. Per accedere ad un campo della struttura si utilizza l'operatore ".":

a1.wp_cval=8;

Dove a1 è il nome dell'elemento struct e wp_cval è il campo a cui si vuole accedere. Adesso il campo wp_cval è inizializzato al valore 8.

wp_char *wp_p;

In questo modo si dichiara un puntatore alla struttura che può essere inizializzato nel seguente modo:

wp_p=&a1;

Per accedere ad un campo della struttura a1 tramite il puntatore si usa l'operatore "->":

wp_p->wp_cval='x';

I campi della struct possono essere anche degli array o addirittura altre struct. Una cosa utile è che una struttura può anche contenere un puntatore ad una struttura dello stesso tipo.

Le strutture, assieme alle funzioni, possono venir definite in un file header che poi verrà incluso nel codice sorgente del programma.

Vedi esempi:

  Senza member function (C like):   Con member function (C++ like):  
  Header file dello STASH   Header file dello STASH  
  File con le definizioni della struttura   File con le definizioni della struttura  
  File sorgente   File sorgente  
         

HOME


 

STRUTTURE E FUNZIONI

Ogni funzione che lavora con una struttura deve ricevere alla chiamata un puntatore alla struttura in questione: questo per poter accedere ai campi della struttura. Ma una funzione può essere dichiarata anche all'interno della struct stessa: questa è una member function. Le member function non hanno bisogno di puntatori per lavorare all'interno della struttura, e possono accedere direttamente alle variabili definite nella struttura. Le member function vengono definite all'esterno della struct tramite l'operatore "::":

int wp_char::f1(int){...}

Se si definiscono due funzioni con lo stesso nome ma una member di una struttura e una normale, ci potrebbero essere dei problemi di ambiguità. In particolare, se la funzione viene utilizzata all'interno della member con lo stesso nome è necessario farla precedere da "::":

  int f1(int);             // funzione esterna  
  ...  
  int wp_char::f1(int){    // funzione member di wp_char  
  ...  
  a=::f1(3);  // chiamata alla funzione f1 esterna  
  ...}  

Una volta definita la funzione f1 la si può chiamare su un elemento di tipo wp_char nel seguente modo:

x=a1.f1(3);

E' da notare che una struttura con member functions è quasi una classe dove le functions sono i metodi e i campi sono gli attributi. Una volta creata la struttura gli elementi di tipo struct sono le istanze della classe, cioè gli oggetti.

Vedi esempio

HOME


 

INCLUSIONE DI HEADER FILES

Quando si includono nel codice sorgente gli header files che contengono la dichiarazione di strutture e la definizione di funzioni, bisogna assicurarsi che lo stesso header file venga incluso una volta sola (altrimenti si avrebbero più dichiarazioni delle stesse variabili). Per evitare questo tipo di problema è bene inserire nel file header le seguenti istruzioni:

 

#ifndef Flag_name

 
  #define Flag_name  
  ...  
  "codice dell'header"  
  ...  
  #endif  

 L'istruzione #define Flag_name serve per definire un nome (che solitamente coincide con quello del file header) che identifica l'header stesso. Quando il file viene incluso l'istruzione #ifndef Flag_name controlla se Flag_name è già stato definito in precedenza all'interno del codice sorgente. Se è così passa direttamente alla linea #endif (cioè non include il file header). Se Flag_name non è stato ancora definito nel codice sorgente vuol dire che l'header file non è stato incluso in precedenza: viene allora definito Flag_name (per evitare successive inclusioni) e viene incluso il codice del file header. Questa sequenza di istruzioni è presente in tutti gli header predefiniti del C++.

Vedi esempio

HOME