domenica 28 ottobre 2012

Definire una funzione membro costante

Una funzione costante non può modificare un membro dati della sua classe o richiamare una funzione non costante della sua classe. Perché esistono queste restrizioni? Riguarda ciò di cui si ha veramente bisogno. Se non si vede alcuna necessità nel modificare i dati di una funzione membro, è sempre una buona idea dichiarare quella funzione come costante. Protegge la classe dall'alterazione involontaria dei dati, e rende evidenti le intenzioni del programmatore ad altri programmatori che ne analizzino il codice.
             int DaiFame() const;

Questo tipo di dichiarazione viene effettuata mediante la parola chiave const posta alla fine del nome della funzione, nella sua intestazione. Ed è quello che è stato scritto nel corpo della classe Roditore con la funzione DaiFame(). Questo significa che DaiFame() non può modificare in alcun modo i membri dati non statici dichiarati nella classe Roditore, o richiamare qualunque funzione non statica. In questo caso la funzione si limita solo a restituire il valore di I_Fame. Solitamente tutte le funzioni membro Dai (Get) sono definite come costanti.

venerdì 26 ottobre 2012

Definire funzioni accessorie

Una funzione accessoria permette accesso indiretto ai dati membro. Poiché i_Fame è privato, deve essere scritta la funzione accessoria DaiFame(), per restituire questo valore di dato.
int Roditore::DaiFame() const
{ return i_Fame;
}

Mentre per richiamare la funzione al lavoro viene inserita nel main() la seguente linea:
cout << “Chiama DaiFame():” << topo.DaiFame() << endl;

A questo punto ci si domanda come mai si vogliano dichiarare i membri dati come privati per darne pieno accesso tramite le funzioni accessorie. La risposta sta nel non garantire pieno accesso. Come mostrato nella funzione MettiFame(), la quale attribuisce il valore a i_Fame.
void Roditore::MettiFame( int fame)
{ if (fame < 0 ) cout << “Non ci puo' essere un valore negativo della fame.” << endl;
else i_Fame = fame;
}

In questa funzione accessoria, per prima cosa ci si assicura che il valore attribuito dalla funzione sia maggiore di zero. Altrimenti il valore viene dichiarato illegale, pertanto non viene modificato. In questo modo MettiFame() protegge l'integrità di i_Fame, cosicché non possa avere valore negativo. Come fatto qui molti programmatori iniziano il nome delle loro funzioni accessorie con le parole Dai (Get) e Metti (Set).

mercoledì 24 ottobre 2012

Impostare i livelli di accesso

Come le funzioni, gli oggetti possono essere trattati come entità incapsulate. Questo vuol dire in generale, che è meglio evitare la modifica diretta o l'accesso ai dati membro. Invece è consigliabile chiamare una funzione membro, permettendo all'oggetto di mantenere i propri membri dati ed assicurarne l'integrità. Fortunatamente, è possibile rafforzare le restrizioni ai dati membro quando viene definita la classe impostandone i livelli di accesso.

Presentare il programma Roditore privato

Il programma Roditore privato dimostra i livelli di accesso ai membri della classe, introducendo nella classe Roditore una restrizione ai livello di accesso che costituiscono il suo livello di fame. La classe fornisce due funzioni membro, una che permette l'accesso ai dati e l'altra che permette di modificarli. Il programma crea un nuovo roditore e indirettamente accede e modifica il livello di fame del roditore attraverso queste funzioni. Comunque, quando il programma tenta di modificare il valore di fame, usando un valore illegale, la funzione membro che ne permette il cambiamento, lo comprende e ne vieta l'operazione. Infine il programma utilizza un valore legale per impostare il livello di fame. Il codice è il seguente:
// Roditore privato
//Dimostrazione dei livelli di accesso
#include <iostream>
using namespace std;
class Roditore
{ public:
Roditore( int fame =0 );
int DaiFame() const;
void MettiFame( int fame);
void Saluto();
private: //sezione privata
int i_Fame;
};
Roditore::Roditore( int fame ): i_Fame (fame)
{ cout << “E' nato un nuovo roditore!” << endl;
}
int Roditore::DaiFame() const
{ return i_Fame;
}
void Roditore::MettiFame( int fame)
{ if (fame < 0 ) cout << “Non ci puo' essere un valore negativo della fame.” << endl;
else i_Fame = fame;
}
void Roditore::Saluto() //definizione funzione membro
{ cout << “Ciao, io sono un roditore. Questo è il mio livello di fame ” << i_Fame << “.\n”;
}
int main()
{
Roditore topo(5);
// cout << topo.i_Fame; // illegale i_Fame è privato
cout << “Chiama DaiFame():” << topo.DaiFame() << endl;
cout << “Chiamare MettiFame() con -5” << topo.MettiFame( -5 );
topo.MettiFame(15);
topo.Saluto();
return 0;
}

 

Specificare i livelli di accesso Pubblico e Privato

Ogni classe di funzioni e dati possiede un livello di accesso, il quale determina da dove il programma ha accesso ad essi. Così, viene sempre specificato quali hanno accesso pubblico usando la parola chiave public. In Roditore, la sezione pubblica viene introdotta con la linea:
public:
Roditore( int fame =0 ); 
 
Utilizzando questa parola chiave, sottolineo che ogni membro o funzione che segue sino ad una diversa specifica di livello deve essere ritenuta pubblica. Questo significa che ogni parte del programma ha accesso ad essi. Per cui il codice del programma può richiamare queste funzioni della classe Roditore.
Dopodiché viene definita la sezione privata con la seguente linea di codice:
private: //sezione privata
int i_Fame;

Usando private, ogni membro dati o funzione che segue (sino a diversa specifica) deve essere privata. Questo vuol dire che solo il codice nella classe Roditore ha accesso diretto ad esse. Poiché i_Fame viene dichiarato in questa sezione, solo il codice presente in Roditore può accedere direttamente al membro dati i_Fame dell'oggetto. Per cui tentare di accedere ad esso attraverso la funzione main(), crea un'operazione illegale la quale genera un errore nel programma.
// cout << topo.i_Fame; // illegale i_Fame è privato

E' possibile generare sezioni private in una classe seguite da sezioni pubbliche ripetendo l'accesso ai modificatori. Infine ogni classe membro dichiarata è privata per default, a meno di modifiche al livello di accesso specifiche.

martedì 23 ottobre 2012

Uso dei Costruttori

Quando sono istanziati degli oggetti, spesso si desidera una qualche inizializzazione, solitamente con l'assegnazione di valori ai membri dati. Fortunatamente la classe prevede una speciale funzione membro chiamata costruttore che automaticamente viene richiamata ogni qualvolta un oggetto viene definito. La grossa convenienza è nell'uso del costrutto per effettuare l'inizializzazione del nuovo oggetto.

Il programma Roditore costruttore

Questo programma dimostra l'uso dei costruttori. Il programma istanza un nuovo oggetto Roditore, il quale richiama il suo costruttore automaticamente. Per prima cosa viene annunciata la nascita di un nuovo roditore. Quindi assegna un valore alla variabile fame del roditore, provando che il costruttore di fatto inizializza il Roditore. Il codice è il seguente:
// Roditore costruttore
// Dimostrazione dei costruttori
#include <iostream>
using namespace std;
class Roditore
{ public:
               int i_Fame;
               Roditore( int fame =0 ); // prototipo del costruttore
               void Saluto(); // funzione membro prototipo
};
    Roditore::Roditore( int fame ) // costruttore
    { cout << “E' nato un nuovo roditore!” << endl;
       i_Fame = fame;
    }
    void Roditore::Saluto() //definizione funzione membro
    { cout << “Ciao, io sono un roditore. Questo è il mio livello di fame ” << i_Fame << “.\n”;
    }

int main()
{
   Roditore topo(5);
    topo.Saluto();
    return 0;
}

 

Dichiarare e definire un Costruttore

La dichiarazione del costruttore nella classe Roditore è fatta con il seguente codice:
Roditore( int fame =0 ); // prototipo del costruttore

Come si può notare dalla dichiarazione, il costruttore non restituisce alcun valore. Inoltre è illegale definire un valore di restituzione da parte del costruttore. Inoltre non vi è flessibilità nel nome del costruttore, esso deve avere lo stesso nome della classe. Il costruttore vien definito all'esterno della classe stessa con le seguenti istruzioni:
Roditore::Roditore( int fame ) // costruttore
{ cout << “E' nato un nuovo roditore!” << endl;
i_Fame = fame;
}

Il costruttore visualizza un messaggio a schermo, il quale afferma la creazione di un nuovo roditore e inizializza il membro dati i_Fame dell'oggetto con il valore di l'argomento che viene inviato al costruttore. Se non viene inviato alcun valore, l'argomento di default è 0.

 

Chiamare un costruttore automaticamente

Se il costruttore non viene richiamato esplicitamente, comunque non appena vien istanziato il nuovo oggetto, il costruttore è chiamato automaticamente. In main(), il costruttore viene messo in azione dal seguente codice:
Roditore topo(5);

Quanto topo viene istanziato, il costruttore visualizza automaticamente il messaggio “E' nato un nuovo roditore!”. Quindi il costruttore assegna valore 5 alla variabile i_Fame dell'oggetto. Ciò prova che il costruttore ha lavorato, tornando a main(), viene chiama la funzione Saluto() dell'oggetto per essere sicuri, che visualizza “Ciao, io sono un roditore. Questo è il mio livello di fame 5”.

domenica 21 ottobre 2012

Inizializzazione delle classi

Il semplice programma Semplice roditore definisce un nuovo tipo chiamato Roditore, per la creazione degli oggetti. Questo programma utilizza crea due oggetti di tipo Roditore dopodiché assegna ad ognuno di essi un livello di fame. Infine ogni roditore saluta e comunica il suo livello di fame al mondo.
Il codice del programma è il seguente:
// Semplice roditore
// Dimostrazione della creazione di un nuovo tipo
#include <iostream>
using naspace std;
class Roditore \\definizione della classe
{ public:
             int i_Fame;
             void Saluto(); // funzione membro prototipo
};
void Roditore::Saluto() //definizione funzione membro
{ cout << “Ciao, io sono un roditore. Questo è il mio livello di fame ” << i_Fame << “.\n”;
}
int main()
{
  Roditore topo1;
  Roditore topo2;
  topo1.i_Fame =3;
  topo2.i_Fame =7;
  topo1.Saluto();
  topo2.Saluto();
  system(PAUSE);
return 0;
}

Per creare questa nuova tipologia, viene definita una classe di codice che raggruppa i membri dati e le funzioni. Dalla classe è possibile creare singoli oggetti individuali le quali possiedono relative copie delle funzioni e degli oggetti virtuali ed il loro accesso. La classe è come un progetto, così come il progetto definisce la struttura dell'edificio, una classe definisce la struttura di un oggetto. Così come un muratore può costruire parecchie case con lo stesso progetto, il programmatore può definire molti oggetti utilizzando la stessa classe. Mostriamo un poco di codice per cementare questa teoria. La classe viene definita nel programma Semplice roditore con questa riga:
class Roditore \\definizione della classe

La definizione della classe inizia con la parola chiave class, seguita dal nome della classe. Per convenzione i nomi delle classi iniziano con la lettera maiuscola. Il corpo della classe è racchiuso dalle parentesi graffe e termina con un punto e virgola.

Definizione delle funzioni membro

Le funzioni membro possono essere definite all'esterno della definizione della classe. Al di fuori della classe Roditore, viene definita la funzione membro Saluto(), la quale dice ciao e mostra il livello di fame del roditore.
void Roditore::Saluto() //definizione funzione membro
{ cout << “Ciao, io sono un roditore. Questo è il mio livello di fame ” << i_Fame << “.\n”;
}

La definizione è simile a quella di tutte le altre funzioni ad eccezione di una cosa, il prefisso della funzione è Roditore:: Quando viene definita una funzione membro all'esterno della classe, essa deve essere qualificata con il nome della classe e l'operatore di risoluzione di scopo, in modo che il compilatore sappia che essa appartiene alla classe. Nella funzione membro il valore di i_Fame viene visualizzato con cout. Questo significa che Saluto() mostra il valore di i_Fame per l'oggetto specifico per il quale viene richiamata la funzione. In questo caso viene semplicemente mostrato il livello di fame. E possibile accedere ai membri dati e alle funzioni membro di un oggetto semplicemente usando il suo nome membro.

Istanziare gli oggetto

Quando viene creato un oggetto, esso viene istanziato dalla classe. Di fatto, oggetti specifici sono chiamati istanze della classe. In main(), sono state istanziate due Roditori dalla classe.
Roditore topo1;
Roditore topo2;

Come risultato vi sono due oggetti di tipo Roditore, topo1 e topo2.

Accedere ai membri dati

E' ora di far lavorare i roditori, per prima cosa viene assegnato loro un livello di fame.
Topo1.i_fame = 3;

Il codice precedente assegna un livello 3 di fame a dato membro i_Fame del topo1. Così come è possibile accedere a una funzione membro di un oggetto mediante l'operatore selezione, vale anche per i dati membro. E' possibile inoltre ottenere il valore di un dato membro mediante questa procedura. In questo programma topo1 e topo2 sono due istanze di Roditore, ognuna esiste indipendentemente e ha propria identità. Ciascuna possiede un livello di i_Fame diverso.

Richiamare le funzioni membro

Nell'istruzione successiva vengono richiamate le funzioni di Roditore, in questo caso Saluto().
topo1.Saluto();
topo2.Saluto();

La risposta del programma alle due istruzioni sarà la seguente: “Ciao sono un roditore è il mio livello di fame è 3.”, richiamato dal primo topo. Il secondo topo invece dirà: “Ciao sono un roditore è il mio livello di fame è 7.”, ognuno di essi ha visualizzato il proprio dato membro i_Fame.

martedì 16 ottobre 2012

Le Classi

La programmazione orientata agli oggetti (OOP) è un modo diverso di pensare riguardo alla programmazione. E' la metodologia moderna che viene usata nella creazione della maggior parte dei videogiochi (e altro software commerciale). Nella OOP, vengono definiti diversi tipi di oggetti e le loro relazioni che li legano affinché possano interagire. Abbiamo già lavorato con oggetti definiti dalle librerie, ma la caratteristica chiave della OOP è la possibilità di realizzare oggetti di tipo proprio. Nei seguenti posto verrà spiegato come:
  • Creare nuove tipologie di oggetti definendone le classi
  • Dichiarare i membri dati delle classi e le funzioni membro
  • Istanze degli oggetti dalle classi
  • Definire i livelli di accesso
  • Dichiarare membri dati statici e relative funzioni

sabato 13 ottobre 2012

L'oggetto String II

Creazione Oggetti string

La prima cosa che viene effettuata nella funzione main() è l'inizializzazione delle stringhe effettuata in tre modalità diverse:
                       string parola1 = “Il gioco”;
                       string parola2( “finisce”);
                       string parola3(3,'!');

Nella prima linea del gruppo viene semplicemente creato l'oggetto stringa parola1 utilizzando l'operatore di assegnazione, allo stesso modo delle altre variabili viste in precedenza. Come risultato, la parola1 è “Il gioco”. Successivamente vien creata la parola2 , l'oggetto string viene inizializzato usando le parentesi della funzione. Come risultato, parola2 è “finisce”. Infine viene creata parola3 inserendo in un paio di parentesi un numero seguito da un carattere. Come risultato la stringa di parola3 è “!!!”.

Concatenazione degli oggetti

Per creare il successivo oggetto string, frase, si concatenano i primi tre oggetti string.
            string frase = parola1 + “ ” + parola2 + parola3;

Come risultato si ottiene la seguente frase, “Il gioco finisce!!!”.
Da notare come l'operatore +, il quale lavora solitamente con i numeri, possa concatenare anche oggetti string. Ciò avviene grazie al suo overloading, che permette di ottenere buoni risultati anche in contesti che non sono familiari. Overloading degli operatori ridefinisce le operazioni effettuabili con un operatore conosciuto, in un contesto prima indefinito. La libreria string consente quindi di sommare le stringhe tra loro mediante l'operatore + definendone la concatenazione degli oggetti.

Uso della funzione size()

Ora diamo un'occhiata alle funzioni membro della libreria string, la prossima ad essere utilizzata è la funzione size(). 
           cout << “La frase ha ” << frase.size() << “ caratteri in essa.\n”;

frase.size() richiama la funzione membro size() dell'oggetto string chiamato frase attraverso un operatore di selezione (.). La funzione size() restituisce un valore intero privo di segno che corrisponde al numero di caratteri dell'oggetto string. Poiché l'oggetto string è “Il gioco finisce!!!”, il numero di caratteri restituiti è 19. Certamente una stringa diversa restituisce un numero di caratteri differente.

Indicizzazione di un Oggetto string

Un oggetto string è la memorizzazione di una sequenza di caratteri, char. E' possibile accedere al singolo carattere fornendo il numero di indice mediante l'operatore []. Come mostrato nell'esempio.
         cout << “Il carattere in posizione 0:” << frase[0] << “\n”;

Il primo elemento della sequenza ha indice 0. Nella precedente istruzione, frase[0] ha valore I, e poiché comincia con zero, l'ultimo carattere nell'oggetto string è frase[18], anche se vi sono 19 caratteri in essa.
         cout << “Cambiamo carattere in posizione 0.\n”; frase[0]= 'E';
         cout << “La frase adesso e':” << frase << “\n”;

E' anche possibile cambiare un singolo carattere dell'oggetto string usando lo stesso operatore e riassegnandolo. Dopo aver cambiato in frase il carattere in E, la frase è quindi diventata “El gioco finisce!!!”.

Iterare con un'oggetto string

Data la nostra conoscenza dei cicli for e degli oggetti string, è molto semplice elencare i singoli caratteri di una stringa. Come mostrato di seguito.
       for (int j=0; j < frase.size(); ++j)
            cout << “Carattere in posizione ” << j << “e': ” << frase [j] << endl;

Il ciclo viene ripetuto sino a che la posizione del carattere sia valida nella stringa frase. Comincia con 0 e arriva sino a 18. Durante ogni ciclo un carattere dell'oggetto string viene scritto sullo schermo tramite frase[j].

Usare la funzione find()

Adesso viene mostrata la funzione find() per controllare se vi siano corrispondenze letterali tra due stringhe ed il contenuto di frase. Per prima cosa viene controllata la stringa “finisce”.
        cout << “La stringa 'finisce' e' in posizione:” << frase.find(“finisce”) << endl;

In questa funzione membro viene restituito il valore numerico del carattere nel quale la stringa comincia nella stringa frase. Nel caso di “finisce”, la funzione find() restituisce un 9. ma cosa succede nel caso che non si sia ritrovata la stringa da ricercare?
        if (frase.find (“pera”) == string::npos) cout << “'pera' non si trova nella frase.\n”;

Poiché pera non esiste in frase.find() questa funzione restituisce una costante speciale definita dalla libreria string, con la quale avere accesso tramite string::npos. In questo caso viene mostrata la scritta sullo schermo 'pera' non si trova nella frase. Informalmente string::npos rappresenta un numero di posizione inesistente. Ed è il risultato perfetto da restituire per mostrare che non vi sono ricorrenze tra le due stringhe.

Usare la funzione erase()

La funzione membro erase() consente di rimuovere sotto-stringhe parziali da un oggetto string. Un modo per chiamare questa funzione è specificare il punto d'inizio e la lunghezza della sotto-stringa.
      frase.erase(2,5);
      cout << “La frase adesso e':” << frase << “\n”;

Un altro modo per richiamare questa funzione è dare solo la posizione d'inizio della sotto-stringa, in questo modo saranno eliminati tutti i caratteri successivi a partire dalla posizione indicata sino alla fine della stringa.
      frase.erase(5);

Tuttavia esiste un ultima modalità per richiamare la funzione erase() priva di argomenti, in questo caso la stringa viene svuotata completamente. Pertanto frase diventa una stringa priva di caratteri.
      frase.erase();
      cout << “La frase adesso e':” << frase << “\n”;

Usare la funzione empty()

La funzione membro empty() restituisce un valore booleano il quale assume true se l'oggetto string in questione è privo di caratteri, false in tutti gli altri casi. Viene utilizzato nel seguente codice:
       if (frase.empty()) cout << “\n La frase e' vuota!\n”;

Poiché frase è stata cancellata, frase.empty restituisce valore true pertanto sullo schermo viene mostrata la scritta “La frase e' vuota!”.

mercoledì 10 ottobre 2012

L'oggetto String

L'oggetto string, è il modo perfetto per lavorare con sequenze di caratteri, sia nel caso che si stia lavorando ad un programma per le parole crociate che per memorizzare il nome del giocatore al completo. La stringa è in realtà un oggetto, il quale fornisce un proprio gruppo di funzioni membro che permettono di fare varie manipolazioni sull'oggetto string, e sono state definite in modo intuitivo così che l'operatore possa già conoscerle.

Presentare il programma Prova String

Il programma seguente permette di utilizzare l'oggetto string che contiene “Il gioco finisce!”, e permette di conoscerne la lunghezza, l'indice di posizione di ogni carattere, e se contiene o no una certa sotto-stringa. In aggiunta il programma cancella una parte della string.
Il codice è il seguente:
//Dimostrare oggetto string
#include<iostream>
#include<string>
using namespace std;
int main()
{
         string parola1 = “Il gioco”;
         string parola2( “finisce”);
         string parola3(3,'!');
         string frase = parola1 + “ ” + parola2 + parola3;
         
         cout << “La frase:” : << frase << “\n”;
         cout << “La frase ha ” << frase.size() << “ caratteri in essa.\n”;
         cout << “Il carattere in posizione 0:” << frase[0] << “\n”;
         cout << “Cambiamo carattere in posizione 0.\n”; frase[0]= 'E';
         cout << “La frase adesso e':” << frase << “\n”;
         
         for (int j=0; j < frase.size(); ++j)
                cout << “Carattere in posizione ” << j << “e': ” << frase [j] << endl;
         cout << “La stringa 'finisce' e' in posizione:” << frase.find(“finisce”) << endl;
         if (frase.find (“pera”) == string::npos) cout << “'pera' non si trova nella frase.\n”;
         
          frase.erase(2,5);
          cout << “La frase adesso e':” << frase << “\n”;
          frase.erase();
          cout << “La frase adesso e':” << frase << “\n”;
          if (frase.empty()) cout << “\n La frase e' vuota!\n”;
     return EXIT_SUCCESS;
}

sabato 6 ottobre 2012

Comprendere gli Oggetti

Nei precedenti post è stato illustrato come le informazioni individuali sono memorizzate nelle variabili e come queste variabili possono essere manipolate attraverso l'uso di operatori e funzioni. Tuttavia la maggior parte delle cose rappresentate in un videogioco sono oggetti. Essi sono cose che combinano qualità (come il livello di vita o energia) e abilità (la possibilità di muoversi, attaccare o difendersi dal fuoco). Spesso non ha senso parlare di qualità individuali e abilità separate le une dalle altre. Fortunatamente la maggior parte dei moderni linguaggi di programmazione permette di lavorare con oggetti software (spesso chiamati solo oggetti) che combinano dati e funzioni. Un elemento dati di un oggetto è chiamato membro dati, mentre una funzione di un oggetto è chiamata funzione membro Come esempio concreto, si può pensare ad un'astronave nemica. Questa astronave aliena può essere un nuovo tipo di oggetto chiamato Astronave, definito nel gioco dal programmatore, la quale può avere un membro dati per il suo livello di energia, e una funzione membro per utilizzare la sua arma. In pratica il suo livello di energia è rappresentata da un valore int chiamato energia; mentre la sua arma viene comandata dalla funzione faiFuoco().
Ogni oggetto che condivide la stessa struttura di base, ne condivide membri dati e funzioni. Tuttavia come oggetto individuale, questo valore dei dati può differire da oggetto ad oggetto. Uno squadrone di cinque astronavi possiederà cinque livelli di energia diversi. Ogni astronave inoltre utilizzerà la sua arma individualmente richiamando la propria funzione faiFuoco().
Una buona caratteristica degli oggetti è che essi possono essere utilizzati senza doverne conoscere la struttura interna, così come è possibile accendere la radio senza doverla costruire da zero. Bisogna solo conoscere quali sono le sue funzioni ed i suoi membri dati. Questi oggetti possono essere memorizzati in variabili, come tipologie pre-costruite. Così l'astronave nemica può essere memorizzata in una variabile del tipo Astronave. E' possibile accedere ai membri dati e alle funzioni membro attraverso l'operatore (.), inserendolo dopo il nome della variabile. Così se si desidera che l'astronave aliena, nave, spari con la sua arma solo se il suo livello di energia è maggiore di 10, si può scrivere il seguente codice:

if (nave.energia > 10) nave.faiFuoco();

nave.energia accede al dato energia dell'oggetto, mentre nave.faiFuoco() richiama la funzione membro. Anche se è possibile utilizzare nuovi tipi di oggetti, descritti dal programmatore. Ti è possibile lavorare con tipologie predefinite di oggetti. Oggetto dei prossimi post.

Utilizzare ciclo For senza dichiarazioni

E' possibile utilizzare un istruzione nel ciclo for priva di dichiarazione nel modo seguente:

for ( ; conteggio < 10; )

In questo caso l'istruzione è priva dell'inizializzazione della variabile e dell'incremento. L'istruzione è valida in quanto necessita solo che la variabile conteggio venga dichiarata prima del suo utilizzo nel ciclo for, e deve essere incrementata all'interno del ciclo stesso. Un esempio è il seguente:

int conteggio = 0;
for ( ; conteggio < 10; ){
                                      istruzioni;
                                      conteggio++; }

Questo tipo di ciclo non presenta alcun errore per la compilazione, è perfettamente legale.