INTRODUZIONE AL C++

Transcript

INTRODUZIONE AL C++
INTRODUZIONE AL C++
1) Cos'è il C++
E' un linguaggio ad alto livello che ingloba il linguaggio C, col quale è completamente compatibile
(ogni programma C viene compilato da un compilatore C++) ed al quale aggiunge alcune
caratteristiche quali i concetti di CLASSE.
2) Cos'è una CLASSE?
Una classe è un tipo di dato che consente la PROGRAMMAZIONE AD OGGETTI, cioè una
programmazione più adatta ad implementare programmi di grosse dimensioni.
3) Qual è il più semplice programma C++?
E' il seguente:
//programma ciao, mondo
#include <iostream>
using namespace std;
int main()
{
cout << "Ciao, Mondo!" << endl;
system("pause");
}
4) Cosa significa la linea: //programma ciao, mondo
Significa che tale linea è un commento, ovvero una frase che viene posta per chiarire quanto si sta
facendo. Ogni commento inizia col simbolo // e termina a fine riga.
5) Esiste un modo per fare un commento su più righe?
Si può fare un commento che inizia col simbolo /*
commento può occupare più righe.
e termina col simbolo */. In questo modo il
6) Cosa significa la riga di programma: #include <iostream>
Tale riga non è una istruzione ma è una DIRETTIVA per il compilatore. Essa dice al compilatore di
includere (al posto della direttiva) il contenuto del file iostream (che si trova nella sottocartella
include della cartella che contiene il compilatore). Tale file contiene i prototipi di tutte le funzioni
che serviranno per l'ingresso e l'uscita dei dati, come la funzione cout.
7) Cos'è una funzione?
Una funzione è una parte di programma (sottoprogramma) dotata di un titolo e di un corpo.
Il titolo della funzione specifica il tipo del valore di uscita, il nome della funzione e l'elenco degli
argomento con la relativa specifica di tipo.
8) Può fare un esempio di titolo di funzione?
int somma(int x, int y)
1
Il precedente è un titolo di funzione (se il titolo è seguito dal carattere ; diventa un prototipo) che
restituisce un intero (int) e si applica a due argomenti x,y entrambi interi.
9) Cosa significa la riga: using namespace std; ?
Un programma C++ molto complesso può essere costituito da più file ciscuno dei quali verrà
compilato separatamente. I risultati della compilazione vengono assemblati da un programma che
si chiama LINKER.
Se un identificatore (nome di variabile, di funzione eccetera) viene definito extern in un file F1 esso
verrà riconosciuto anche da tutti gli altri file linkati assieme a F1. Si possono così creare dei conflitti
se lo stesso identificatore viene ridefinito per errore in file diversi. Per evitare tali conflitti si
consente di ridefinire lo stesso identificatore su file diversi a condizione di creare degli SPAZI DEI
NOMI (namespace) e di porre gli identificatori su namespace diversi.
10) Cos'è il namespace std?
Nel C++ tutti gli identificatori della libreria standard sono inseriti tutti entro il medesimo namespace
che si chiama std
(standard)
11) E' possibile evitare l'uso dell'istruzione: using namespace std?
Si, ma in questo caso gli identificatori che forniscono i nomi di tutte le funzioni contenute nella
libreria standard come cin e cout devono essere preceduti da std:: (scope resolution)
Ad esempio il programma precedente può scriversi:
#include <iostream>
int main()
{
std::cout<< "Ciao, Mondo! "<<std::endl;
system("pause");
}
12) Cosa significa la riga: int main()
?
Tale riga è il titolo della funzione principale del programma. Tale funzione deve essere sempre
presente in un programma ed è la funzione che viene eseguita per prima.
La parola int significa che la funzione restituisce un intero. Una funzione qualsiasi restituisce un
valore mediante una istruzione del tipo:
return valore ;
Nel caso della funzione main tale istruzione può essere omessa. Se invece nel main si inserisce
l'istruzione return valore; il valore deve essere un intero.
13) Che utilità può avere l'istruzione return valore; inserita nel main?
Il main può essere chiamato dal sistema operativo. Inserire tale istruzione può servire al sistema
operativo per sapere ad esempio se il programma è stato eseguito fino alla fine oppure se c'è stata
una uscita anticipata in seguito ad un errore nel programma.
14) Che cos'è una variabile, come si dichiara il suo tipo, come le si assegna un valore?
Le variabili sono lo strumento fondamentale col quale si comunicano i dati fra l'utente ed il sistema
di calcolo (computer). Le variabili servono cioè sia per l'INPUT dei dati di ingresso, sia per
l'OUTPUT dei dati di uscita, frutto dell'elaborazione.
2
15) Quali sono gli attributi di una variabile?
Sono il suo NOME, il suo TIPO, ed il suo VALORE.
16) Come si assegna un nome ad una variabile?
Una variabile segue la sintassi degli IDENTIFICATORI, ovvero:
<identificatore>=<lettera>/<identificatore><cifra>
Cioè un identificatore è una lettera seguita da una qualsiasi sequenza di lettere o cifre. Si noti che
in C++ il carattere _ (underscore) è considerato una lettera.
Sono esempi di identificatori:
numero, num1, num, numComplesso, num_complesso, x, x0
Non sono naturalmente ammessi come identificatori i TERMINI RISERVATI che esprimono nomi di
funzioni predefiniti o termini utilizzati in istruzioni del linguaggio (if, int, main …)
17) Un programma C++ è generalmente scritto in lettere minuscole. E' consentito l'uso delle
maiuscole?
Il programmatore può utilizzare lettere maiuscole in un identificatore, tuttavia il compilatore
distingue le minuscole dalle corrispondenti maiuscole. Ad esempio le variabili
numero e NUMERO sono due variabili distinte.
18) Come si dichiara che una variabile ha tipo intero?
Si dichiara premettendo il termine riservato int prima del nome della variabile.
Ad esempio per dichiarare che la variabile numero è intera si scriverà:
int numero;
19) Quali sono i tipi numerici fondamentali?
Sono short, int, long, float, double, long double. Ciascuno di questi tipi ha una
occupazione di memoria che dipende dal compilatore utilizzato. Per il DEV-CPP i precedenti tipi
occupano rispettivamente 2 (short), 4(int), 8(long), 4(float) ,8 (double), 12 (long double) come si
rileva facendo girare il seguente programma:
//occupazione di memoria dei diversi tipi
#include <iostream>
using namespace std;
int main()
{
cout<<"dimensioni tipo short"<<sizeof(short)<<endl;
cout<<"dimensioni tipo int:"<<sizeof(int)<<endl;
cout<<"dimensioni tipo long:"<<sizeof(long)<<endl;
cout<<"dimensioni tipo double:"<<sizeof(double)<<endl;
cout<<"dimensioni tipo long double:"<<sizeof(long double)<<endl;
system("pause");
}
Si noti infatti che l'operatore sizeof fornisce il numero di byte occupato dal tipo posto come suo
argomento.
20) Cosa significa short?
Significa numero intero avente occupazione minima di memoria (2 byte nel DEV-CPP).
Tenendo presente che due byte sono 16 bit, e che un bit serve per il segno, il massimo short vale
allora 2^15-1= 32767. Mentre il minimo short vale -32768. Ciò può essere controllato col
programma:
3
//massimo e minimo short
#include <iostream>
#include <climits>
using namespace std;
int main()
{
cout<<"massimo short="<<SHRT_MAX <<endl;
cout<<"minimo short="<<SHRT_MIN <<endl;
system("pause");
}
Si noti infatti che il file climits riporta i valori massimi e minimi dei vari tipi numerici. Tali valori sono
indicati dalle costanti:
SHRT_MAX, SHRT_MIN
(short)
INT_MAX, INT_MIN
(int)
LONG_MAX, LONG_MIN (long)
21) Cosa significano int e long?
Significano INTERO ed INTERO LUNGO. Nel Dev-Cpp un intero occupa 4 byte, mentre un intero
lungo occupa 8 byte. Varia quindi il numero massimo che si può rappresentare nei due casi.
Precisamente vale:
2^31-1 = 2.1 10^9 circa per gli int
Vale 2^63-1 = 9.2 10^18 per i long
22) Cosa significano float e double?
Significa numero in virgola fluttuante (o mobile). Tale numero viene rappresentato nel Dev-Cpp con
4 byte (32 bit). Di questi 32 bit la maggior parte viene riservata alla mantissa ed i rimanenti
(probabilmente 8) all'esponente.
Si osservi che nei linguaggi artificiali il carattere che separa la parte intera da quella decimale è
il punto (e non la virgola!)
Con il formato float possono essere rappresentati correttamente numeri aventi 8 cifre. Mentre con il
formato double (doppia precisione) possono essere rappresentati correttamente numeri con 17
cifre.
Ciò può essere visto col programma:
//cifre significative
#include <iostream>
using namespace std;
int main()
{
const float a=-1.23456789012345678;
const double b=-1.23456789012345678;
cout.precision(20);
cout<<"a="<< a <<endl;
cout<<"b="<< b <<endl;
system("pause");
}
4
Tale programma fornisce un valore di a che risulta corretto solo per le prime 8 cifre.
Fornisce un valore di b che risulta corretto per le prime 17 cifre significative.
Si noti la presenza della istruzione cout.precision(20);
Tale istruzione imposta la precisione a 20 cifre, consentendo di apprezzare tutte
le cifre esatte dei due numeri a,b. Senza tale istruzione la precisione sarebbe
stata 6 (valore di default), per cui non si sarebbero potute osservare tutte le cifre
esatte di a, b, ma sarebbero risultate errate tutte le cifre dalla settima in poi!
23) Quali sono le operazioni che si possono fare coi tipi numerici?
Con i tipi interi (short, int e long) si possono fare le normali operazioni aritmetiche:
1) + (somma)
2) (differenza)
3) *
(prodotto)
4) /
(divisione)
5) % (modulo ovvero calcolo del resto di una divisione fra interi positivi)
6) ++ (incremento)
7) -- (decremento)
Si noti perciò che non esiste un operatore che consenta di effettuare il calcolo della potenza.
24) Come mai il seguente programma fornisce come risultato a/b=0?
#include <iostream>
using namespace std;
int main()
{
cout<<"2/4="<<2/4<<endl;
system("pause");
}
Sia il numero 2 che il numero 4 sono interi, perciò il compilatore fornisce il risultato come numero
intero. Se almeno uno dei due numeri fosse stato float, anche l'altro numero sarebbe stato
convertito in float ed il risultato sarebbe stato un float. Ad esempio scrivendo
#include <iostream>
using namespace std;
int main()
{
cout<<"2.0/4="<<2.0/4<<endl;
system("pause");
}
si ottiene come risultato 0.5.
5
La regola è allora che se in una espressione aritmetica esistono operandi di tipo diverso, tutti gli
operandi vengono convertiti nel tipo ad occupazione di memoria maggiore. Quindi il risultato sarà
di quest'ultimo tipo.
25) Si può convertire una espressione di tipo A in una di tipo B diverso?
Sì. La sintassi utilizzata è la seguente: (tipoA) espressione_tipoB
Ad esempio:
int main()
{
int A=100000;
cout << "A=" << A << endl;
cout << " (short) A = " << (short) A << endl;
system("pause");
}
//cast di tipo
fornisce:
A = 64000
(short) A = −1536
Il motivo dell'ultimo output sta nel fatto che il numero 100000 è stato convertito in uno short (intero
breve) il quale occupa 16 bit. Questo numero di bit non è sufficiente ad esprimere il numero
100000, per cui questo viene troncato portando ad un risultato errato.
Si osservi che per brevità nell'esempio precedente, come in quelli che
seguiranno, si sono omesse le direttive per il compilatore, che generalmente
sono le tre seguenti:
#include <iostream>
#include <conio.h>
using namespace std
e che vanno poste ad ogni inizio programma.
26) In quali casi può essere utile il cast di tipo?
In molte situazioni. Ad esempio ogni carattere viene codificato con un codice numerico ad 8 bit
(byte). In molti casi si desidererebbe conoscere il codice associato ad un carattere non presente
sulla tastiera in modo da potere ottenere il carattere dalla pressione del tasto Alt accompagnata dal
codice. Ad esempio il carattere ~ (tilde) si ottiene dalla pressione del tasto Alt accompagnata dal
numero 126. Un programma che fornisce tale informazione è il seguente:
int main()
{
int A=126;
cout << "A=" << A << endl;
cout << " (char)A= " << (char) A <<endl;
system("pause");
}
Tale programma prende l'intero 126 e lo converte in un carattere (la tilde) che verrà stampato dalla
cout. Naturalmente per ottenere la stessa uscita si sarebbe potuto scrivere:
int main()
{
char A=123;
cout << "A=" << A << endl;
system("pause");
}
Si è utilizzata la prima versione solo per illustrare il cast di tipo.
6
27) Come si esprimono le costanti a virgola mobile?
I numeri a virgola mobile sono i numeri con il punto. Dotati cioè di una parte intera e di una parte
decimale. Tali numeri sono detti a virgola mobile poiché si può spostare il punto, che separa le due
parti, utilizzando una opportuna potenza di 10.
Ad esempio il numero 0.123 posso anche scriverlo come 123.0 e−3. In quest'ultima espressione
la lettera
e
rappresenta la parola esponente. Infatti il numero che segue rappresenta
l'esponente da dare al 10 affinché le due espressioni coincidano.
Ciò può essere visto col programma:
int main()
{ A=0.123;
cout << "A=" << A << endl;
cout << "123.0 e−3=" << 123.0e−3 <<endl;
system("pause");
}
che fornisce per A due valori identici. Si noti che la base e deve essere seguita immediatamente
dall'esponente, senza lasciare alcuno spazio.
28) Come si esprimono le costanti carattere e le costanti stringa?
Una costante di tipo carattere viene posta fra apici semplici, mentre una costante stringa viene
posta fra doppi apici.
Ad esempio:
int main()
{ char A='1';
string B="esempio";
cout <<"A=" << A << endl;
cout << "B=" << B <<endl;
system("pause");
}
29) Come si assegna ad una variabile un valore costante?
Mediante un operatore di assegnazione. Si noti che gli operatori di assegnazione sono diversi.
Precisamente si possono avere assegnazioni semplici o composte.
Le assegnazioni semplici si effettuano con l'operatore =
Ad esempio:
x=2;
assegna alla variabile x, dichiarata in precedenza short, int, long, float o double, il valore 2.
Naturalmente se non vi è compatibilità fra il valore assegnato ed il tipo dichiarato si produrrà un
errore che tuttavia non viene segnalato dal compilatore.
Ad esempio il programma:
#include <iostream>
using namespace std;
int main()
{ short A=100000;
short B=100000;
cout <<"A+B=" << A+B << endl;
system("pause");
}
7
è perfettamente corretto dal punto di vista sintattico, perciò il compilatore non fornisce alcun
messaggio di errore. Tuttavia quando viene eseguito produce:
A+B = −62144
Risultato che è chiaramente sbagliato!
Il motivo è che una variabile short (2 byte) non può contenere il numero 100000.
30) Come si effettua una assegnazione composta?
Facendo precedere l'operatore di assegnazione da uno dei seguenti dieci operatori:
+
(somma)
−
(differenza)
*
(prodotto)
/
(rapporto)
%
(modulo)
&
(AND bit a bit)
|
(OR bit a bit)
^
(EXOR bit a bit)
>>
(shift a destra)
<<
(shift a sinistra)
Ad esempio la sezione di codice:
x = 3;
x += 2;
cout << " x= " << x ;
produce x= 5
Infatti il significato di x += 2 è x = x+2.
Analogo significato hanno gli altri operatori di assegnazione composta.
31) Come si stabilisce la precedenza fra gli operatori?
Esistono delle tabelle che elencano tutti gli operatori del C++ in ordine di precedenza decrescente.
In linea di massima si tenga presente
a) Gli operatori con la massima priorità sono quello UNARI, cioè con un solo operando
b) A seguire vengono gli operatori aritmetici binari
c) Quindi gli operatori di shift e quelli relazionali (ovvero <,<=, >, >=, ==, !=)
d) Gli operatori logici sui bit e quelli sulle espressioni logiche
e) L'operatore ternario di condizione ?:
(condizione?espressione1:espressione2)
f) Gli operatori di assegnazione
Vedremo i vari operatori un po’ alla volta.
32) Come si associano gli operatori in una espressione priva di parentesi?
Si associano quasi tutti da sinistra a destra. Fanno eccezione gli operatori di assegnazione che si
associano da destra a sinistra. Ad esempio l'espressione: a+=b+=2; va intesa in questo modo: a
+=(b+=2); che significa: prendi il valore di b e sommagli 2. Prendi il valore di a e sommagli quello
che hai ottenuto prima. Il programma:
int main()
{
int a=3,b=4;
a+=b+=2;
cout << "a=" << a <<endl;
system("pause");
}
produce a=9.
8
33) Quali sono le principali istruzioni del C++?
Sono
a) le istruzioni condizionali:
b) le istruzioni iterative:
if-else,
for,
switch
while,
do-while,
34) Qual è la sintassi ed il significato della istruzione if-else?
La sintassi dell'istruzione di selezione if è la seguente:
if (<condizione>)
<istruzione1 semplice o composta>
else
<istruzione2 semplice o composta>;
Nella precedente <condizione> indica una espressione logica che possa cioè assumere i valori
vero o falso. Tale espressione va posta fra parentesi tonde. Si tenga presente che nel C++ esiste il
tipi semplice bool che assume solo i valori true e false. Tuttavia si è mantenuta la compatibilità col
C ammettendo che il valore 0 (zero) indica il FALSO, qualsiasi altro valore, anche di tipo float che
non sia zero, indica il VERO.
<istruzione semplice o composta> indica invece una qualsiasi istruzione o sequenza di istruzioni
racchiuse fra parentesi graffe.
Il significato è evidente:
Se la <condizione> è vera verrà eseguita la <istruzione1>, altrimenti verrà eseguita la
<istruzione2>.
Ad esempio il programma:
int main()
{
float a=0;
if (a)
cout<<"a=vero \n";
else
cout <<"a=falso \n";
system("pause");
}
produce
a=falso
35) Come si costruisce una espressione condizionale?
Utilizzando gli operatori relazionali:
==
(uguaglianza:si noti la differenza rispetto all'assegnazione)
>
(maggiore)
<
(minore)
>=
(maggiore od uguale)
<=
(minore od uguale)
!=
(diverso)
36) Si possono ottenere condizioni composte utilizzando gli operatori logici?
Si, sono utilizzabili gli operatori:
&&
and)
||
(or)
!
(not)
Ad esempio:
9
int main()
{
bool a=0,b=0;
if ((a)||(b))
cout << "vero \n";
else
cout <<"falso \n";
system("pause");
}
produce l'uscita falso. Cambiando i valori iniziali di a e di b si può ottenere la tavola di verità del
simbolo || (or).
Si noti che ciascuna condizione semplice e l'inera condizione composta vanno racchiuse fra
parentesi.
37) Esiste un operatore condizionale ternario?
Si. E' l'operatore
?:
In questo caso i due caratteri non costituiscono una unità simbolica, ma nel loro uso sono separati.
L'uso dell'operatore condizionale ternario è il seguente:
Il valore della espressione
condizione?espressione1: espressione2
coincide col valore dell'espressione1 se la condizione è vera; coincide invece col valore della
espressione2 se la condizione è falsa.
Ad esempio:
int main()
{
(2>3) ? cout << "maggiore \n" : cout <<"minore \n";
system("pause");
}
Il precedente programma scrive minore, dal momento che la condizione (2<3) è falsa.
Si noti che cout<<variabile/costante è una espressione particolare il cui valore è il valore della
variabile oppure è la costante posta a video.
38) Esiste un operatore che consente di inserire due o più espressioni laddove la sintassi prevede
l'inserimento di una singola espressione?
Si. E' l'operatore , (virgola). Ad esempio:
int main()
{ int a;
(2>3)? a=2 , a++ : a=3 , a++;
cout << "a=" << a <<endl;
system("pause");
}
Nel precedente, l'espressione posta fra i simboli ? e : è una espressione composta, ottenuta
applicando l'operatore virgola. Ovvero
a=2 , a++ Anche l'espressione posta dopo il simbolo : è
composta. Essa è infatti a=3 , a++
Il risultato del programma si ottiene calcolando quest'ultima espressione composta, che fornisce il
valore 4, ottenuto INCREMENTANDO il valore assegnato ad a.
10
39) Qual è il significato dell'operatore unario ++ ?
E' quello di INCREMENTO dell'espressione che lo segue o lo precede. Si noti infatti che tale
operatore può essere prefisso (esempio ++a) oppure postfisso (esempio a++).
Nel caso che l'espressione ++a venga assegnata alla variabile b , PRIMA viene incrementata a e
poi avviene l'assegnamento a b. Viceversa se a++ viene assegnato a b, prima avviene
l'assegnamento e poi l'incremento.
Ad esempio:
int main()
{
int a=1,b;
b=++a;
cout<<"b dopo PREINCREMENTO="<<b<<endl;
a=1;
b=a++;
cout<<"b dopo POSTINCREMENTO="<<b<<endl;
system("pause");
}
Il primo valore di b vale 2 (piochè a viene prima incrementata e poi assegnata)
Il secondo valore di b vale 1, poiché a viene prima assegnata e poi incrementata.
40) Come viene effettuata la lettura dei dati di ingresso al programma?
Mediante lo streaming di ingresso standard (cin). Questo è un canale associato normalmente
all'unità di ingresso principale, ovvero alla tastiera.
Lo stream cin viene utilizzato facendo seguire il nome cin dall'operatore >> (che indica la direzione
dei dati di ingresso) seguito dal nome della variabile che deve essere letta e che è stata dichiarata
in precedenza.
Ad esempio:
int main()
{
short int a=3;
cout<<"Inserisci un valore numerico"<<endl;
cin>>a;
cout<<"a="<<a<<endl;
system("pause");
}
Il precedente programma chiede di inserire un valore numerico. Se tale valore è del tipo dichiarato
per la variabile allora il valore viene assegnato alla variabile a. Se viceversa tale valore non è
compatibile con il tipo dichiarato la variabile, quest'ultima conserva il suo valore iniziale (in questo
caso 3). Se ad una variabile intera non viene assegnato alcun valore iniziale, per default viene
inizializzata a zero.
Se viene assegnato un valore non del tipo dichiarato, ma compatibile con questo, viene fatta la
conversione dal un tipo all'altro.
Ad esempio se la variabile a viene dichiarata intera e le viene assegnato il valore 3.2, la variabile
riceverà il valore 3.
41) E' possibile leggere più variabili contemporaneamente?
Si. Ad esempio il programma:
11
int main()
{
int numero1, numero2;
char operatore;
cout<<"Inserisci numero1 operatore numero2"<<endl;
cin>>numero1>>operatore>>numero2;
cout<<"numero1="<<numero1<<endl;
cout<<"operatore="<<operatore<<endl;
cout<<"numero2="<<numero2<<endl;
system("pause");
}
Consente di inserire la stringa 123+456 ottenendo le assegnazioni:
numero1=123
operatore=+
numero2=456
Tuttavia si deve stare molto attenti a che vi sia rispondenza fra i tipi dichiarati per le variabili ed i
valori inseriti, poiché se per errore si batte un solo valore errato potranno risultare errati i valori
assegnati a molte variabili.
42) Come viene effettuato l'output dei dati?
Mediante lo streaming standard cout seguito dall'operatore << (che indica la direzione dei dati di
uscita), seguito a sua volta dalla variabile (o dalla costante) che deve essere mandata sull'unità di
uscita standard (schermo).
Si possono inviare all'uscita i valori di più variabili (o costanti) a condizione di separarle
dall'operatore <<.
Ad esempio:
int main()
{
int num1=123,num2=456;
cout<< "numero1=" << num1<< "\n numero2=" << num2<< endl;
system("pause");
}
fornisce:
numero1=123
numero2=456
43) Cosa significa il simbolo \n che appare nel programma precedente?
Nel programma precedente si è utilizzato il carattere speciale \n (newline), detto carattere di
escape, ottenuto facendo seguire il carattere \ (backslash) dalla lettera n (iniziale di newline).
Caratteri analoghi sono:
\t
(tab)
\a
(alarm)
\"
(virgolette)
\'
(apice)
\\
(backslash)
\0
(carattere NULL : terminatore di stringa)
44) Quali sono le funzioni associate allo stream di uscita cout?
Lo stream di uscita cout è un oggetto, ovvero una variabile di tipo classe, la quale, come si dirà nel
seguito è un aggregato di variabili e di funzioni, utilizzabili dagli oggetti della classe.
Le variabili di una classe vengono dette ATTRIBUTI.
Le funzioni sono dette METODI.
Gli attributi della classe cout sono i seguenti:
12
a) width(intero)
Consente di definire il numero di caratteri del campo in cui verrà scritto il dato in uscita con
l'istruzione cout successiva a width().
Ad esempio l'istruzione
cout.width(10);
significa che il dato che verrà scritto con la successiva cout verrà scritto in un campo di 10caratteri.
Si noti che l'impostazione precedente vale solo per il prossimo cout, non per i successivi.
Ad esempio:
int main()
{
int num1=123,num2=456;
cout.width(10);
cout<<num1<<endl;
cout<<num2<<endl;
system("pause");
}
Produce:
123
456
Se il numero di caratteri del dato è inferiore a quelli del campo, allora i caratteri del campo non
utilizzati saranno degli spazi, oppure saranno i caratteri specificati con l'istruzione:
cout.fill('carattere').
b) precision(intero)
Vale solo per i NUMERI REALI, e consente di fissare il numero di cifre utilizzato per visualizzare il
numero. Se questo è più grande della precisione fissata, viene arrotondato.
Ad esempio:
int main()
{
float num=12.3456;
cout.precision(4);
cout << "num=" << num << endl;
system("pause");
}
produce num=12.35
Si noti che per default la precisione è 6. Per cui il programma:
int main()
{
double num=12.3456789;
cout << "num=" << num << endl;
system("pause");
}
produce num=12.3457
OVVERO ARROTONDA LA SESTA CIFRA, producendo un errore anche se il tipo scelto per
rappresentare la variabile è ampiamente sufficiente per il valore assegnato a quest'ultima. L'errore
precedente si può eliminare facendo precedere la cout da: cout.precision(9);
c) flag(argomento)
Consente di allineare a sinistra il dato nel campo (argomento=ios::left), oppure a destra (ios::right) .
L'allineamento è mantenuto per tutte le stampe successive. Per default è a destra.
Consente anche di fissare la notazione dei numeri reali che può essere fissa (ios::fixed), oppure
scientifica (ios::scientific). Nel caso di notazione scientifica la precisione fornisce il numero di cifre
dopo la virgola.
13
CICLI
45) In che modo è possibile ripetere un blocco di istruzioni più volte?
Utilizzando l'istruzione do-while.
Si noti che questa istruzione prevede che il blocco delle istruzioni sia eseguito almeno una volta,
dopodiché sarà RIESEGUITO fintantoché la condizione che segue il while rimane vera.
La sintassi è:
do
{
sequenza di istruzioni;
}while (condizione_di_ripetizione);
Ad esempio un ciclo che continua a leggere un numero fintantochè il valore inserito è minore di 10
o maggiore di 20 è il seguente:
int main()
{
int x;
do
{
cout<<"Inserisci un numero fra compreso fra 10 e 20, estremi inclusi. \n";
cin>>x;
}while ( x<10 || x>20 );
}
cout << "numero inserito:"<<x<<"\n";
system("pause");
Si noti che la lettura del numero deve essere ripetuta finchè (fintantochè) si verifichino delle
condizioni indesiderate.
Tali condizioni sono x<10 oppure x>20. Il simbolo || equivale all'operatore logico OR. Perciò la
condizione di riesecuzione del ciclo è una condizione composta dalle due condizioni semplici
precedenti, tramite l'operatore OR.
46) Quali sono gli operatori logici che si possono utilizzare per ottenere una condizione composta?
Sono gli operatori:
!
NOT
||
OR
&&
AND
Per ottenere una condizione composta occorre utilizzare gli operatori logici di negazione,
congiunzione e disgiunzione, ovvero gli operatori logici NOT, AND e OR. Tali operatori si
esprimono coi simboli
!
(NOT)
&&
(AND)
||
(OR)
Quando si scrive una espressione condizionale senza parentesi occorre fare attenzione alla
PRECEDENZA fra gli operatori. Ad esempio gli operatori relazionali di uguaglianza, maggioranza e
minoranza hanno la precedenza rispetto agli operatori logici binari.
Ad esempio il programma:
14
int main()
{
int x;
do
{
}
cout<<"Inserisci numero maggiore di 10";
cin>>x;
}while (!x<10) ;
entra in un loop infinito. Infatti la condizione: (!x<10) a causa del fatto che l'operatore unario ! ha la
precedenza rispetto all'operatore relazionale <, viene intesa come segue:
Nega il valore logico di x (se x diverso da 0 la negazione logica è zero, mentre se x=0 la
negazione logica produce 1) e controlla se quello che ottieni è minore di 10.
Poiché quello che si ottiene è sempre minore di 10 non si esce mai dal ciclo.
Fra i due operatori && e || ha la precedenza &&. Ciò può essere visto col programma:
int main()
{
bool A=true, B=false, C=false;
cout << "A || B && C=" << (A||B && C) <<endl;
system("pause");
}
che fornisce A || B && C=1 (cioè vero). Ciò significa che viene effettuato prima l'and e poi l'or
(altrimenti si sarebbe ottenuto 0 (cioè falso)
47) Qual è l'istruzione iterativa più usata?
E' l'istruzione for. Utilizzando solo tale istruzione assieme all'assegnazione si possono scrivere una
quantità innumerevole di programmi.
La sintassi è la seguente:
for( espr_iniziale; condizione_esecuzione; espr_finale)
{sequenza_istruzioni;}
L' espressione iniziale viene valutata prima di eseguire il ciclo. Si noti che anche una semplice
assegnazione è una espressione (una espressione è una stringa di costanti, variabili ed operatori).
La condizione_di esecuzione viene valutata per stabilire se rieseguire il ciclo. Il ciclo si riesegue
fintantochè tale condizione è vera.
Infine la espressione finale viene eseguita al termine di ogni ciclo.
Ad esempio il seguente programma esegue la somma dei primi 10 interi.
const int N=10;
int main()
{
int i, somma=0;
for (i=1; i<=N; i++)
somma=somma+i;
cout << "somma dei primi 10 interi =" << somma << endl;
system("pause");
}
15
48) Qual è il significato del termine riservato const che appare nel programma precedente?
La istruzione const int N=10; è una DICHIARAZIONE DI COSTANTE. Essa consente non solo di
dichiarare il tipo della costante, ma anche di assegnargli un valore che non potrà essere cambiato
nel corso dell'esecuzione del programma.
49) E' possibile omettere una o più espressioni che appaiono nella sintassi del for?
Si, ma non si può omettere il corrispondente punto e virgola. Ad esempio il programma precedente
si può scrivere:
const int N= 10;
int main()
{
int i=1, somma=0;
for ( ; i<=N ; i++)
somma=somma+i;
}
//si noti che l'espressione iniziale del for è vuota
cout<< "somma dei primi 10 interi=" <<somma <<endl;
system("pause");
Ovvero si può inizializzare la variabile i fuori dal ciclo, tuttavia il ; che separa la prima espressione
del for dalla condizione di esecuzione, utilizzata generalmente per inizializzare le variabili del ciclo,
deve apparire nel for.
50) Si possono utilizzare due for innestati l'uno dentro l'altro?
Certo. Come istruzione del ciclo for può essere utilizzata qualsiasi altra istruzione. Quindi anche un
altro for. Ad esempio il seguente programma legge (e scrive) una matrice per righe.
//matrice
#include <iostream>
using namespace std;
const int N= 3;
int main()
{
int i, j, A[N][N];
cout << "Inserisci una matrice intera 3x3" << endl;
for ( i=0 ; i<N ; i++)
{
for ( j=0 ; j<N; j++)
cin >> A[i][j];
cout << endl;
}
cout<< "Matrice:" <<endl;
for ( i=0 ; i<N ; i++)
{
for ( j=0 ; j<N ; j++)
{
cout.width(6);
cout << A[i][j];
}
cout << endl;
}
system("pause");
}
16
ARRAY
51) Cosè una matrice?
Una matrice è un ARRAY a più dimensioni. A sua volta un array è un insieme di elementi, tutti dello
stesso tipo, caratterizzati da un NOME e da un indice intero.
Quando si fa riferimento ad un particolare elemento di un array ,l'indice di tale elemento va posto in
parentesi quadre.
Ad esempio: const int A[10]={1,2,3,4,5,6,7,8,9,10};
dichiara che A è un array costituito da 10 elementi interi e assegna un valore iniziale ad ogni
elemento. Volendo riferirsi al primo elemento di A si utilizzerà la scrittura: A[0].
Ad esempio volendo sommare tutti i valori di A si utilizzerà un for del tipo:
int somma=0;
for(i=0;i<10;i++) somma=somma+A[i];
Il programma:
int A[10] = {1,2,3,4,5,6,7,8,9,10};
int main()
{
cout<<"Vettore=";
for (int i=0; i<10; i++)
cout << A[i] << '\t';
system("pause");
}
dopo aver dichiarato l'array A ed avergli assegnato dei valori iniziali, fa la stampa dei suoi elementi.
Gli elementi sono separati dal carattere \t (tab)
Si noti che il valore dell'indice iniziale deve essere zero. Perciò se l'array ha dimensioni N, i
valori dell'indice varieranno da 0 ad N-1
52) E' possibile una uscita anticipata da un ciclo?
Si, utilizzando l'istruzione
oppure l'istruzione
break;
continue;
La prima provoca l'uscita immediata dal ciclo in cui è inserita.
La seconda provoca il salto alla fine del ciclo e l'esecuzione del ciclo successivo.
Ad esempio:
int main()
{
for (int i=0; i<20; i++)
{ if (i%2==1)continue;
cout<<i<<'\n';
}
system("pause");
}
17
produce in uscita l'elenco dei numeri pari minori di 20. Infatti ogni volta che si incontra un numero
dispari, ovvero che i%2==1 (resto della divisione per due uguale ad uno) si salta a fine ciclo
attuale, saltando l'istruzione di stampa.
Se si fosse scritto break al posto di continue si sarebbe ottenuto la stampa del solo numero 0,
poiché break provoca l'uscita definitiva dal ciclo.
STRINGHE
53) Come si gestiscono le stringhe nel C++?
Le stringhe nel C++ sono considerate degli array di caratteri terminanti col carattere speciale
'\0' (NULL).
Per leggere una stringa si può utilizzare la funzione gets(stringa) contenuta nella libreria conio.h
Ad esempio il programma seguente legge e scrive una stringa:
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
char s[80];
cout<<"Inserire stringa:"<<endl;
gets(s);
//è preferibile rispetto a cin<<s poichè quest'ultima non consente
//di inserire nella stringa spazi bianchi
cout<<"s="<<s;
system("pause");
}
54) Esiste una libreria standard che consente operazioni sulle stringhe?
La libreria cstring consente di effettuare sulle stringhe una serie di operazioni. Fra queste:
sono importanti:
a) strcpy(s1,s2)
copia la stringa s2 sulla stringa s2
b) strcat(s1,s2)
concatena la stringa s2 alla stringa s1)
c) strlen(s)
fornisce il numero di caratteri di s, compresi gli spazi
d) strstr(s1,s2)
fornisce la sottostringa di s1 che inizia con s2
Il funzionamento delle precedenti funzioni è illustrato dal programma:
#include <iostream>
#include <cstring>
#include <conio.h>
using namespace std;
int main()
{
char s1[80]="prima stringa lunga",
s2[80]="seconda stringa",
s3[80]="";
//s3=stringa vuota
cout << "lunghezza s1=" << strlen(s1); getch();
cout << " sottostringa di s1 iniziante con stringa:" << strstr(s1,"stringa"); getch();
strcpy(s3,s1);
//copia s1 su s3
cout << "s3=" << s3 << endl;
strcat(s3,s2);
//concatena s2 ad s3
cout << "s3=" << s3 << endl;
system("pause");
}
18
STRUTTURE
54) Cosa sono le strutture?
Le strutture sono tipi di dati molto importanti, perché generalizzando tale tipo nascono le CLASSI
che sono alla base della programmazione ad oggetti (OOP).
Una struttura è un insieme di dati aventi generalmente tipi diversi fra loro e tuttavia riferentesi al
medesimo "oggetto". I divcersi elementi di una struttura sono detti MEMBRI.
Se s è una variabile di tipo struttura si accede ad un membro m di s con la scrittura s.m
Il seguente programma definisce la stuttura punto come un insieme dei campi interi x ed y, dichiara
la variabile p di tipi punto e ne legge il valore.
#include <iostream>
using namespace std;
struct punto
{
int y;
};
int x;
int main()
{ struct punto p;
p.x=2;
p.y=3;
cout << "punto=(" << p.x << "," << p.y<< ")";
system("pause");
}
55) Si possono definire array di strutture?
Si. Ad esempio il programma seguente definisce la struttura studente . Dichiara un array di N
studenti. Legge i dati relativi agli N studenti e li scrive.
#include <iostream>
using namespace std;
struct studente
{
char cognome[16];
int eta;
float mediaVoti;
};
const int N=3;
//N=numero studenti
int main()
{
int i;
struct studente s[N];
for(i=0; i<N; i++)
{
cout << "Inserisci cognome studente " << i+1 << "\t: " ;
cin >> s[i].cognome;
cout << "Inserisci eta' studente " << i+1 << "\t: " ;
cin >> s[i].eta;
cout << "Inserisci media voti studente "<< i+1 << "\t: " ;
cin >> s[i].mediaVoti;
}
cout<<"\nDati inseriti:"<<endl;
for(i=0; i<N; i++)
{
cout << "\ncognome studente "<< i+1<<"\t:" ;
cout << s[i].cognome<<endl;
cout << "eta studente "<< i+1 << "\t\t:";
cout << s[i].eta<<endl;
cout << "media voti studente " << i+1<< "\t:";
cout << s[i].mediaVoti<<endl;
}
system ("pause");
}
19