Dichiarazioni

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:

OperatoreSignificato
*è 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:

  1. f è una funzione che restituisce un

  2. puntatore ad un

  3. array di

  4. puntatori a

  5. 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())[],

Operatori di Relazione

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).

OperatoreSignificato
<Minore di
<=Minore o uguale di
>Maggiore di
>=Maggiore o uguale di
==Uguale a
!=Diverso da

Operatori Logici

Le relazioni possono comparire in espressioni logiche come operandi degli operatori logici.

OperatoreSignificato
&&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 espressioniforniscono 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;

}

if, if-else

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;

}

Diramazione multipla: switch-case

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;

}

Cicli

Un ciclo rappresenta un blocco da ripetere se una certa condizione risulta vera.

Ciclo while

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;

}

ciclo do … while

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

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:

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;

}

Esercizi proposti

  1. 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

  2. Confrontare la frequenza osservata con la probabilità di ciascun possibile risultato.

  3. 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

Operatore ?:

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:

  1. Si dichiara un puntatore a file.

  2. la funzione main

  3. si apre in lettura il file input.txt

  4. si dichiara la variabile di tipo double acquisita da input

  5. si dichiarano variabili di tipo double

  6. che in effetti però, sono costanti

  7. contenenti le fasce di sconto

  8. si dichiara la variabile di output Totale

  9. 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: