Una dichiarazione in linguaggio C contiene il tipo della variabile e, in un'espressione contenente alcuni operatori, l'identificatore della variabile.
Gli operatori usati in una dichiarazione sono:
Operatore | Significato |
* | è un puntatore a … |
() | è una funzione che restituisce un … |
[] | è un array di … |
Esempi:
Esempio di dichiarazione | interpretazione |
int x; | x è un intero. |
int *x; | x è un puntatore a intero. |
int x[]; | x è un array di interi. |
int x(); | x è una funzione che restituisce un intero. |
int *x(); | x è una funzione che restituisce un puntatore a intero. |
Nell'ultima dichiarazione sono presenti due operatori. L'interpretazione della dichiarazione si ottiene applicando le regole di precedenza degli operatori. In questo caso le parentesi hanno la precedenza sull'asterisco.
Si supponga di avere un array x di puntatori a stringhe:
elementi del vettore | valore puntato | |
x[0] | → | Napoli |
x[1] | → | Roma |
x[2] | → | Torino |
… | → | … |
Si vuole dichiarare una funzione f che elabori l'array e ritorni il puntatore all'array. La dichiarazione
completa deve essere:
f è una funzione che restituisce un puntatore ad un array di puntatori a char.
La dichiarazione che si vuole costruire quindi viene ottenuta dalle specifiche individuando gli operatori presenti:
f è una funzione che restituisce un
puntatore ad un
array di
puntatori a
char.
L'espressione al punto 1 si scrive: f(),
al punto 2 diventa: *f(),
Al punto 3 bisogna introdurre le parentesi quadre: *f()[], Però potrebbe sorgere un dubbio: si tratta di
un array di funzioni che restituiscono un puntatore a char o si tratta di una funzione che restituisce un array di puntatori
a char?
Per evitare l'ambiguità, come in un'espressione algebrica, si racchiude tra parentesi l'espressione
da sviluppare per prima, quindi: (*f())[],
Al punto 4 la dichiarazione richiede un asterisco: *(*f())[],
Infine, al punto 5 l'espressione completa è char *(*f())[],
La CPU esegue le istruzioni di un programma nello stesso ordine in cui le trova: una dopo l'altra. Le istruzioni di diramazione offrono la possibilità di passare ad eseguire (sempre in ordine sequenziale) le istruzioni che si trovano in un'altra zona del programma.
La diramazione può essere imperativa o condizionata. la diramazione imperativa, o di salto, specifica una nuova zona del programma da cui continuare l'esecuzione.
Anche la diramazione condizionale specifica una nuova zona del programma da cui continuare l'esecuzione, ma premette una condizione da verificare, altrimenti l'esecuzione continua, normalmente, con l'istruzione successiva.
Una relazione è un'operazione tra due operandi dello stesso tipo (int, double, char, …) e fornisce un risultato di tipo booleano (true o false).
Operatore | Significato |
< | Minore di |
<= | Minore o uguale di |
> | Maggiore di |
>= | Maggiore o uguale di |
== | Uguale a |
!= | Diverso da |
Le relazioni possono comparire in espressioni logiche come operandi degli operatori logici.
Operatore | Significato |
&& | And
Il risultato è vero se e solo se entrambe le relazioni sono vere |
|| | Or
Il risultato è vero se e solo se almeno una relazione è vera |
! | Not
Il risultato è vero se la relazione è falsa, è falso se la relazione è vera |
Esempi. Assumendo che le variabili x e y siano di tipo intero, con x = 6 e y = 2,
le seguenti espressioni | … | forniscono il risultato seguente |
!(x > 2) | → | false |
(x > y) && (y > 0) | → | true |
(x < y) && (y > 0) | → | false |
(x < y) || (y > 0) | → | true |
Per rappresentare un valore logico (true o false) basterebbe un solo bit, ma la CPU accede a una locazione di memoria intera, non a uno solo dei suoi bit, quindi in C++ un boolean è rappresentato con un intero e si assume che false sia il valore 0 e true sia un valore diverso da 0.
Quindi, in un'espressione logica, la stringa "Hello world" ha valore true, il valore 2 è true, e qualsiasi variabile intera contenente un valore diverso da 0 è true. Di conseguenza: l'espressione !x fornisce il valore false e x && y fornisce il valore true.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
int a=2, b=6, x;
cout << "inserisci un numero: ";
cin >> x;
if (x>=a && x<=b) cout << endl << x << " e' compreso tra " << a << " e " << b << endl;
else cout << endl << x << " e' esterno all'intervallo [" << a << ", " << b << "]" << endl;
if (x<=a || x>=b) cout << endl << x << " non e' compreso tra " << a << " e " << b << endl;
if (x<=a && x>=b)
cout << endl << "non si verifica mai che x e' minore di a e maggiore di b" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
L'istruzione if è un'istruzione di salto condizionato:
viene valutata una relazione e, se
vera, viene eseguita un'istruzione o un blocco di istruzioni, se falsa non viene eseguita l'istruzione specificata
ma si esegue l'istruzione successiva.
La sintassi dell'istruzione if è
if (Test) istruzione oppure if (Test) blocco di istruzioni Nota: blocco di istruzioni è una sequenza di istruzioni racchiuse tra parentesi graffe. |
![]() |
Se la relazione fornisce risultato vero l'istruzione, o il blocco di istruzioni, viene eseguito, in ogni caso l'esecuzione del programma continua con l'istruzione successiva.
L'istruzione di diramazione condizionata if then … else … viene usata quando si deve eseguire un'istruzione, o un blocco, se la condizione è vera (ramo then), oppure un'altra istruzione, o blocco, se la condizione è falsa (ramo else).
if(Test) { istruzione 1 } else { istruzione 2 } Nota le parentesi graffe possono essere omesse se bisogna eseguire una sola istruzione. |
![]() |
Ecco un esempio:
#include <iostream>
using namespace std;
int main() {
int x;
int y;
cout << "scrivi un numero intero (<32768)";
cin >> x;
cout << "scrivi un altro intero";
cin >> y;
if(x > y)
cout << x << " è maggiore di " << y << "\n";
else
if(y > x)
cout << y << " è maggiore di " << x << "\n";
else
cout << "x e y sono uguali" << endl;
return 0;
}
Sintassi:
switch (espressione) {
case valore-1:
istruzione A1
istruzione A2
…
break;
case valore-2:
istruzione B1
istruzione B2
…
break;
default:
istruzione Z1
istruzione Z2
…
}
L'istruzione switch valuta l'espressione ed esegue il blocco di istruzioni contenuto nell'appropriato ramo case. Se il valore dell'espressione non corrisponde a nessuno dei valori specificato nei case, vengono eseguite le istruzioni nel ramo default.
Non sono richieste le parentesi graffe per delimitare il blocco contenuto nel case.
L'istruzione break è un'istruzione di salto incondizionato, cioè l'esecuzione non prosegue dall'istruzione successiva ma prosegue dall'istruzione che segue la parentesi graffa di chiusura dell'istruzione switch. Quindi, ad esempio, omettendo break dopo il case N verrebbe eseguito anche il blocco del case successivo.
Esempio di switch-case:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int x;
cout << "Scrivi un numero intero <90: ";
cin >> x;
switch (x) {
case 1:
cout << "L'Italia" << endl;
break;
case 13:
cout << "Sant'antonio" << endl;
break;
case 90:
cout << "La paura" << endl;
break;
default:
cout << "Conosco solo 1, 13 e 90" << endl;
}
cout << "hai dato il valore " << x;
system("PAUSE");
return 0;
}
Un ciclo rappresenta un blocco da ripetere se una certa condizione risulta vera.
Sintassi del ciclo while:
while(Test) { … istruzioni … } | ![]() |
Il blocco di istruzioni viene ripetuto fintantochè la relazione fornisce esito vero. Se la condizione è falsa il blocco viene saltato. Quindi potrebbe anche non essere mai eseguito se la condizione risulta falsa fin dall'inizio.
Esempio:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
int x, y=1, r;
cout << "Quale tabellina vuoi?: ";
cin >> x;
while (y <= 10) {
cout << (r = x*y++) << endl;
}
system("PAUSE");
return 0;
}
Il ciclo do while differisce dal ciclo while perchè il blocco viene eseguito almeno una volta e poi si valuta la condizione per verificare se il ciclo deve essere ripetuto o sospeso.
Sintassi:
do { … blocco … } while(Test); | ![]() |
Si noti che le parentesi graffe sono sempre richieste, anche se il blocco è formato da una sola istruzione. Si noti anche il punto e virgola dopo la condizione specificata con while.
il ciclo for è usato quando si conosce il numero esatto di volte in cui si vuole eseguire il ciclo.
Sintassi:
for(inizializzazione; condizione per ripetere; calcolo del valore successivo) { Istruzioni } | ![]() |
Il ciclo for possiede una variabile di controllo del ciclo che deve comparire nelle tre espressioni contenute tra le parentesi tonde. Esse specificano, nell'ordine:
Il valore iniziale da assegnare alla variabile di controllo prima di iniziare il ciclo,
La condizione che si deve verificare, al termine di ciascun ciclo, affinchè le operazioni vengano ripetute,
La regola per calcolare il valore successivo della variabile di controllo del ciclo.
Le istruzioni racchiuse tra le parentesi graffe costituiscono le operazioni da ripetere. Le parentesi possono essere omesse se c'è una sola istruzione da ripetere.
Esempio di uso del ciclo for. Il seguente programma simula 10 lanci di 2 dadi:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
int k;
for (k=1; k<=10; k++)
cout << "\t" << (rand()%6+1) << "\t" << (rand()%6+1) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Simulare 1000 lanci di 2 dadi e calcolare la frequenza di ciascun esito. Stampare la tabella che riepiloga per ogni esito la frequenza osservata
Esempio:
esito frequenza
2 36
3 66
4 91
5 99
6 138
7 150
8 131
9 128
10 74
11 53
12 34
Confrontare la frequenza osservata con la probabilità di ciascun possibile risultato.
tracciare un grafico della distribuzione di frequenza
Esempio
2: xxxxxxxxxxxx
3: xxxxxxxxxxxxxxxxxxxxx
4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
7: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
8: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
9: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
10: xxxxxxxxxxxxxxxxxxxxxxxx
11: xxxxxxxxxxxxxxxxx
12: xxxxxxxxxxx
Un'istruzione di diramazione if che ad una stessa variabile, assegna, in un caso, il risultato di un'espressione e, nell'altro caso, il risultato di un'altra espressione:
if (a<10) sconto = 0.05;
else sconto = 0.10; |
in linguaggio C viene tradotta con l'operatore ? : nel modo seguente:
sconto = (a<10) ? 0.05 : 0.10; |
Esempio. Si supponga di poter applicare uno tra tre possibili sconti, a seconda della quantità di articoli acquistati.
La soluzione generale consiste nell'usare una serie di if … else if …
if (quantita>50) Totale = quantita*PrezzoUnitario*(1.0-ScontoMax);
else if (quantita>20) Totale = quantita*PrezzoUnitario*(1.0-ScontoMed); else if (quantita>10) Totale = quantita*PrezzoUnitario*(1.0-ScontoMin); else Totale = quantita*PrezzoUnitario; |
Si mostra la soluzione in C, che fa uso dell'operatore ?:
Preparare il file input.txt contenente le righe:
2.50 3 4.20 15 8.30 25 5.20 60 |
in cui su ogni riga vi è una coppia di valori separati da uno spazio: il primo valore è l'importo unitario, il secondo valore è la quantità di articoli acquistati.
Il programma C:
Commenti:
Si dichiara un puntatore a file.
la funzione main
si apre in lettura il file input.txt
si dichiara la variabile di tipo double acquisita da input
si dichiarano variabili di tipo double
che in effetti però, sono costanti
contenenti le fasce di sconto
si dichiara la variabile di output Totale
si dichiara la variabile di input quantità
il ciclo di lettura
Il ciclo while prosegue fintanto che ci sono dati da leggere dal file.
Si legge un double, specificando il formato %lf, poi si legge lo spazio, e lo si scarta, infine si legge la quantità
Al termine del ciclo si chiude il file.
nelle righe da 15 a 19 inserire le seguenti istruzioni, che calcolano il totale, a seconda dello sconto da applicare: