Ho ottenuto il via libera da Levin per postare una guida che scrissi anni orsono per cominciare a smanettare con il C. La posto perchè può essere un buon punto di partenza per tutti quelli che si avvicinano a questo mondo

Chissà che sia la volta buona che appaia la sezione sui tutorial!
Se scovate degli errori e/o delle imprecisazioni, fatemele notare! Così oltre a correggere imparo anche qualcosa!
------------------------------------------------------------
PICCOLA, VELOCE, SUPERFICIALE GUIDA SUL C
come funziona un programma in c:
un programma in c è essenzialmente composto da 3 parti:
il codice sorgente, il codice oggetto, il programma finale (exe).
il codice sorgente è un file di testo. è quello che scrive il programmatore. tutta la programmazione risiede in questo file, denominato di solito <nome_file>.c o <nome_file>.cpp a seconda se si usa il c o il c++.
il codice oggetto è il codice sorgente compilato dal compilatore c/c++. il codice oggetto non è più un file di testo ma è scritto in linguaggio macchina. la trasformazione da parte del compilatore da codice sorgente a codice oggetto può avvenire solo se non ci sono errori di programmazione nel codice sorgente.
in fine, il programma finale, ovvero il file exe che avviate ogni giorno per fare qualsiasi cosa, è il risultato del collegamento (linking) del codice oggetto con le relative librerie del c/c++ (quella standard e quelle che utilizzerete nel vostro programma). il file exe non è altro che una lunghissima fila di bit..
01010101000011011111000111100001
chi è e che ruolo svolge il compilatore? il compilatore è un intermediario tra l'umano e la macchina. poichè sarebbe impossibile scrivere direttamente in linguaggio macchina (oddio, è un sistema che si usa solo in certe occasioni. ad esempio la programmazione di un microchip che ha dei compiti prefissati e fa solo quello (addizioni, sottrazioni, moltiplicazioni, accesso ai dati, etc. etc.)). il compilatore legge il vostro codice e se non ci sono errori, lo traduce in linguaggio macchina, altrimenti vi dice che c'è un errore e precisamente a quale riga si trova. ovviamente dovrete prendere dimestichezza con i vari messaggi di errore che vi perseguiteranno..
il c si avvale di diversi tipi di dato, primitivi e non e definiti dall'utente e di strutture fondamentali per la gestione del flusso.
che cos'è un tipo di dato? un tipo di dato è in parole povere, un tipo di informazione. un informazione può essere un numero, una parola, un file. il computer non fa altro che elaborare informazioni per restituire un risultato.
che cos'è la gestione del flusso? bè abbiamo detto che un programma principalmente elabora le informazioni che gli vengono fornite dall'utente. quindi ci servono delle strutture che fanno fare al programma la cosa numero 1 o la cosa numero 2 a seconda di cosa chiede l'utente. in questo senso si gestisce il flusso del programma. fare A invece che B, fare tante volte una stessa operazione, etc.. etc..
bene, abbiamo parlato dei tipi di dato. quali sono? come si usano?
i tipi di dato sono i seguenti:
integer (numero intero, senza decimali), float (numeri decimali), double (numeri decimali più grandi), bool (vero o falso - disponibile solo se programmate in c++), char (carattere), string (stringa: un insieme di caratteri).
i tipi di dati servono per creare delle variabili (come quelle usate in matematica: x o y) in cui memorizzare le informazioni. quindi a seconda dei tipi di dato che ho descritto prima, possiamo memorizzare diversi tipi di informazioni, tra cui numeri, caratteri, e stringhe di caratteri (se non sapete cos'è una stringa di caratteri, vi faccio subito un esempio: "ciao mi chiamo Lotti. Ho 20 anni" questa è una stringa!)
per
dichiarare una variabile in c/c++, bisogna rispettare questa sintassi
SI PUO DICHIARARE UNA VARIABILE UNA SOLA VOLTA. se si dichiara due volte la stessa variabile (cioè con lo stesso nome) si avrà un errore durante la compilazione
<tipo_di_dato> nomevariabile;
alcuni esempi:
Codice:
int x;
float y;
double pippo;
char carattere;
bool var1;
ho dichiarato 4 variabili: x di tipo int, y di tipo float, pippo di tipo double e carattere è di tipo char.
il punto e virgola (

che sta alla fine di ogni singola riga è necessario. dopo ogni singola istruzione va messo sempre il ; (salvo particolari istruzioni per il controllo del flusso, che vedremo dopo)
ora che abbiamo le nostre variabili, vediamo come fare per "scriverci" dentro dei dati.
inizializzazione di una variabile
Codice:
x=123;
y=12.3;
pippo=0.0123; --> (a grandi linee, una variabile di tipo double ha il doppio della precisione di una float, quindi permette numeri più precisi, cioè più piccoli (o più grandi))
carattere='q';
se non inizializzate una variabile essa avrà un valore "casuale". Non fate operazioni (es: matematiche) con variabili non inizializzate. Il risultato è imprevedibile!
dichiarazione e inizializzazione di una variabile
si può dichiarare e inizializzare nello stesso momento una variabile. si fa così:
<tipo_di_dato> nomevariabile = valore;
Curiosità: quando si dichiara e si inizializza contemporaneamente una variabile, si può omettere il tipo di dato. sarà il compilatore a individuare il tipo di dato giusto per il valore che intendete memorizzare.
Citazione:Curiosità sui bool: il tipo di dato bool è un tipo di dato particolare che può assumere solo 2 valori: true o false. es:
Codice:
bool a=true;
bool b=false;
ma il bello del c/c++ è che qualsiasi espressione logica (quindi anche le condizioni, che vedremo più avanti) dell'algebra di Boole (quella del vero e falso) non vengono solo rappresentate da, appunto, true o false; ma anche dai numeri. precisamente da tutti i numeri
infatti il c/c++ assume che un qualsiasi valore numero diverso dallo 0 (zero) vale come true. mentre solo lo 0, vale come false. In C le variabili bool non esistono. Dovrete pertanto arrangiarvi con gli 0 (false) e i valori != 0 (true)
Le variabili possono essere dichiarate come costanti per evitare involantari cambiamenti del valore preassegnato durante la stesura del codice. oppure si dichiarano costanti quelle variabili che devono memorizzare il valore di una costante matematica come il PI GRECO (3.14).
una variabile costante va dichiarata e inizializzata nello stesso momento, con questa sintassi:
const <tipo_di_dato> <nomevariabile>=<valore>;
esempio: const float PIGRECO=3.14;
OPERAZIONI CON LE VARIABILI
ogni variabile può fare diverse operazioni a seconda del tipo di dato della variabile stessa.
gli operatori più comuni sono i seguenti:
operatori matematici
+ più --> c=a+b;
- meno --> c=a-b;
* moltiplicazione --> c=a*b;
/ divisione --> c=a/b;
% resto della divisione c=a%b;
= assegnazione del valore --> c=a;
++ incrementa di 1 --> a++; o ++a;
-- decrementa di 1 --> a--; o --a;
>> shift a destra --> c=a>>b; --> equivale a c=a * 2^b;
<< shift a sinistra --> c=a<<b; --> equivale a c=a/2^b;
+= --> a+=5; che è uguale a --> a=a+5;
-= --> a-=5; che è uguale a --> a=a-5;
*= --> a*=5; che è uguale a --> a=a*5;
/= --> a/=5; che è uguale a --> a=a/5;
operatori logici
== uguale --> (a==b) --> si usa solo nelle condizioni o nelle espressioni logiche
!= diverso --> (a!=b) --> si usa solo nelle condizioni o nelle espressioni logiche
> maggiore --> (a>b) --> si usa solo nelle condizioni o nelle espressioni logiche
< minore --> (a<b) --> si usa solo nelle condizioni o nelle espressioni logiche
>= maggiore uguale --> (a>=b) si usa solo nelle condizioni o nelle espressioni logiche
<= minore uguale --> (a<=b) --> si usa solo nelle condizioni o nelle espressioni logiche
&& and --> (a==b && c<a) --> si usa solo nelle condizioni o nelle espressioni logiche
|| or --> (a==b || c<a) --> si usa solo nelle condizioni o nelle espressioni logiche
! negazione --> (!a) --> si usa nelle condizioni o nelle espressioni logiche
ATTENZIONE! GLI OPERATORI NON FUNZIONANO ALLO STESSO MODO CON I DIVERSI TIPI DI DATO. ADDIRITTURA CERTI TIPI DI DATO, NON POSSONO UTILIZZARE ALCUNI OPERATORI (esempio: gli operatori matematici non vanno bene con i bool)
USO DELLE PARENTESI: POTETE USARE ESCLUSIVAMENTE LE PARENTESI TONDE () PER DIRE AL COMPILATORE QUALE OPERAZIONE SVOLGERE PER PRIMA (ESATTAMENTE COME IN MATEMATICA, NELLE EQUAZIONI)
esempio di uso dell'operatore + (addizione)
Codice:
int x;
int y;
int c;
x=5;
y=6;
c=x+y;
c vale 11.
per maggiori informazioni riguardo le variabili, gli operatori che si possono usare, etc. etc. leggete le guide che ho postato più su.
CONTROLLO DEL FLUSSO DI UN PROGRAMMA
veniamo alla seconda importantissima parte di questa miniguida.
nei programmi in c tutto si basa sulle funzioni.
DEFINIZIONE DI UNA FUNZIONE
un funzione serve principalmente a non riscrivere il codice. si può infatti utilizzare infinite volte una sola funzione. il bello delle funzioni è che si possono utilizzare anche in altri programmi.
un programma in c/c++ ha sempre una funzione speciale chiamata main dal quale partirà il programma. vediamone un piccolo esempio con il codice scritto prima.
esaminiamola
Codice:
int main(int argc, char **argv) --> la funzione main non deve essere necessariamente scritta così. però in questo modo, la maggior parte dei compilatori non vi darà nessun errore!!
{
int x;
int y;
int c;
x=5;
y=6;
c=x+y;
return 0; --> il return nel main normalmente deve essere sempre 0.
}
<tipo_di_dato> nomefunzione (<parametri_della_funzione>)
{
....
istruzioni
....
eventuale return <variabile_o_valore>;
}
abbiamo il tipo di dato: il tipo di dato che la funzione deve restituire, se scrivete void, la vostra funzione non tornerà nulla. se esprimete un tipo di dato da restituire, dovete necessariamente scrivere nella funzione (alla fine o dove volete) "return <variabile>;" o "return <valore>;"
abbiamo il nome della funzione (che dovete scegliere voi)
abbiamo i parametri della funzione. cioè quei parametri (possono essere quanti ve ne servono) che dobbiamo passare alla funzione poichè essa possa elaborarli

scrivere non scrivere nulla se non dovete passare parametri alla funzione
abbiamo poi il corpo del messaggio in cui dobbiamo scrivere le istruzioni che utilizzeranno le variabili passate alla funzione e tutte quelle che vi servono
alcuni esempi di funzione
int funzione1(); -> restituisce int e non richiede parametri
void funzione2(int a, float b); -> non restituisce nulla ma richiede un intero e un float.
double funzione3(float c, bool e, char h); -> restituisce un double e richiede un float, un bool e un char
void funzione4(); -> non restituisce niente e non richiede parametri
chiamata di una funzione
dopo aver definito una funzione, bisogna utilizzarla..
ci sono 2 chiamate a funzioni a seconda del tipo di dato che la funzione ritorna (e se lo ritorna) per gli esempi utilizzo gli esempi di dichiarazione di funzioni che ho fatto prima.
mentre scrivete il vostro codice digitate il nome della funzione e i relativi parametri (nell'ordine in cui sono stati scritti nella definizione)
1 chiamata: la funzione non ritorna niente.
....
funzione2(35, 12.01);
funzione4();
....
2 chiamata: la funzione ritorna un dato
....
int a;
a=funzione1();
double b;
b=funzione3(9.9, true, 'm');
....
prototipo di una funzione
normalmente un normale programma in c/c++, si struttura così
Codice:
void funzione1(int a)
{
...
...
}
int funzione2()
{
...
...
}
int main(int argc, char **argv)
{
...
...
return 0;
}
ovviamente però questa struttura non è molto utilizzabile, perchè richiede la dichiarazione delle funzioni in un certo ordine, altrimenti non saranno utilizzabili in certe altre funzioni.
allora si ricorre ai prototipi di funzione. riscrivo solo l'esempio, poi se volete approfondire, cercate su internet
Codice:
void funzione1(int a); --> prototipo (il punto e virgola è obbligatorio)
int funzione2(); --> prototipo (il punto e virgola è obbligatorio)
int main(int argc, char **argv) --> main
{
...
...
return 0;
}
void funzione1(int a) --> dichiarazione funzione
{
...
...
}
int funzione2() --> dichiarazione funzione
{
...
...
}
Altre strutture per il controllo del flusso
IF
ecco con questa struttura, il nostro "flusso" girerà a destra o a sinistra, a seconda della condizione che voi imporrete
if(condizione)
{
...
istruzioni
...
}
else
{
...
istruzioni
...
}
esempio:
Codice:
if(a>5) --> se a è maggiore di 5, fai a=a+5 --> a=10;
{
a=a+5;
}
else --> altrimenti a=1;
{
a=1;
}
SWITCH
ma andrebbe usato tutte le volte che l'operazione di confronto deve restituire un risultato compreso in un intervallo di valori conosciuto. Se per esempio sappiamo che x potrà valere solo 1, 2 o 3, è meglio usare lo switch dell'if...else, in quanto l'esecuzione comporta un salto logico e agisce pertanto con la massima velocità.
lo switch è un if con molte "conseguenze". si usa tutte le volte che l'operazione di confronto deve restituire un risultato compreso in un intervallo di valori conosciuto. Se per esempio sappiamo che x potrà valere solo 1, 2 o 3, è meglio usare lo switch dell'if...else, in quanto l'esecuzione comporta un salto logico e agisce pertanto con la massima velocità. Funziona solo con gli interi (e qualche altro tipo particolare di dato, gli
enum se non sbaglio). Si può usare la parola chiave "default" per tutti gestire i casi non previsti. L'assenza di break, porterà ad eseguire il codice sottostante (finchè non si incontra un altro break o finisce lo switch). ecco l'esempio.
Codice:
int var;
....
....
....
switch (var)
{
default:
case 0: var+=5; break;
case 1: var+=3; break;
case 2: var+=1; break;
}
Se var == 3, viene eseguito il default ovvero il caso 0, poichè default non possiede il break.
DO WHILE
esegue un set di istruzioni tante volte finchè la condizione imposta non diventa falsa (ciclo)
do
{
...
istruzioni
...
}
while (condizione);
esempio:
Codice:
int a=10;
do
{
a=a-1;
}
while (a>5);
WHILE
esegue un set di istruzioni tante volte finchè la condizione imposta non diventa falsa (ciclo) A DIFFERENZA DEL DO WHILE, PRIMA VERIFICA LA CONDIZIONE E POI ESEGUE IL SET DI ISTRUZIONI
while (condizione)
{
...
istruzioni
...
}
esempio:
Codice:
int a=10;
while (a>5)
{
a=a-1;
}
FOR
esegue un ciclo (set di istruzioni), verificando prima la condizione, finchè essa non è falsa. da utilizzare insieme ai contatori. ne vedrete l'uso nel prossimo capitolo, gli array.
for(inizializzazione contatore; condizione; incremento contatore)
{
...
istruzioni
...
}
esempio:
Codice:
int i; /*variabile contantore*/
for (i=0;i<10;i=i+1)
{
a=a+5;
b=a-2;
}
NOTA SULLE CONDIZIONI
potete concatenare più condizioni utilizzando gli operatori && e ||
esempio:
if (a>5 && b<4) --> se a è maggiore di 5 e contemporaneamente b è minore di 4
if (a==5 || c>=3) --> se a è uguale a 5 oppure c è maggiore uguale a 3
if ((a>5 && b<4) || c>=3) se (a è maggiore di 5 e contemporaneamente b è minore di 4) oppure c è maggiore uguale a 3
purtroppo anche questa parte un po' più complicata, dovrete impararla a vostre spese
Array
gli array, o vettori, non sono altro che tante (un numero precisato) di variabili DELLO STESSO TIPO, sotto un unico nome.
es: la famiglia rossi ha 4 membri: il primo membro è il papà, il secondo è la mamma, il terzo la sorella maggiore, il quarto il bebè. qual'è il nome collettivo di questi membri messi in un certo ordine? famiglia rossi. questi "membri" sono tutti dello stesso tipo? si, sono tutte persone.
bene gli arrai sono la stessa cosa. facciamo un esempio concreto: siccome sono un bravo scolaro e tengo molto alla mia media scolastica, ho bisogno di un programmino che mi calcoli rapidamente la media aritmetica dei voti che ho preso.
per risolvere questo problema posso percorrere 2 strade:
1 strada) creo una variabile per ogni voto. così facendo però ogni volta che ottengo un nuovo voto, devo modificare il programma.. per aggiungere variabili
2 strada) creo una array contenente x variabili dello stesso tipo e prefisso un x molto grande oppure lo chiedo direttamente in input all'utente
vediamo il codice per la prima strada
Codice:
#include<iostream.h>
int main(int argc, char **argv)
{
int media;
int primovoto;
int secondovoto;
int terzovoto;
int quartovoto;
int quintovoto;
int sestovoto;
....
....
....
int decimovoto;
/*grazie all'uso della libreria iostream.h, ora utilizzo il comando "cin>>" che serve a prendere un input da tastiera per le applicazioni per console (per console si intende il DOS ad esempio). se non capite cosa faccia, non vi preoccupate. pensate solo che in questo momento l'utente deve digitare il voto e premere invio per 10 volte, poichè sto utilizzando 10 variabili*/
cin>>primovoto;
cin>>secondovoto;
cin>>terzovoto;
cin>>quartovoto;
cin>>quintovoto;
cin>>sestovoto;
....
....
....
cin>>decimovoto;
media=(primovoto+secondovoto+terzovoto+....+decimovoto)/10;
/*bene, cin>> serve per prendere un input da tastiera (numero, carattere o parola che sia, dipende poi dalla variabile che deve accogliere il dato) indovinate a che serve cout<<? serve a stampare a video il contenuto della vostra variabile negli applicativi per console (per console si intende il DOS ad esempio) (anche cout<< risiede nella libreria iostream.h)*/
cout<<media;
return 0;
}
bene abbiamo scritto un bel po' di codice.. esattamente 23 righe se si escludono i commenti (sono quelli tra /* e */). e ogni volta che il secchione prende un nuovo voto deve modificare il suo programma e aggiungere una riga per la dichiarazione della variabile, una per la lettura del voto e modificare il calcolo della media.. 3 operazioni in più. bella rottura di palle

immaginate di avere un programma che per esempio deve calcolare la temperatura media delle ore del giorno per tutto un anno.. bè credo che dovrete scrivervi a mano un bel po' di variabili
vediamo il codice per la seconda strada
Codice:
#include<iostream.h>
int main(int argc, char **argv)
{
const int numerovoti=100;
int voti[numerovoti];
int media=0;
int i; /*variabile contantore. serve a scorrere gli elementi dell'array*/
for (i=0; i<numerovoti; i++)
{
cin>>voti[i];
media=media+voti[i];
}
media=media/numerovoti;
cout<<media;
return 0;
}
escludendo le parentesi graffe ho scritto solo 8 righe di codice.. e se devo calcolare la media di più di 100 voti, mi basta cambiare 1 numero.. il valore della variabile numerovoti.
ora sarete convinti dell'utilità degli array. vediamoli in dettaglio.
dichiarazione di un array
la dichiarazione di un array si può fare in diversi modi. faccio prima ad elencare quelli più usati.
int a[20]; --> crea un array di interi da 20 elementi
const int var=20;
int b[var]; --> crea un array di interi a seconda del valore contenuto in var (che è sempre 20)
float c[var]; --> crea un array di float a seconda del valore contenuto in var (che è sempre 20)
bool d[var]; --> crea un array di booleani a seconda del valore contenuto in var (che è sempre 20)
l'importante è che tra le parentesi [] ci sia un numero INTERO e COSTANTE. quindi se si vuole utilizzare un variabile al posto di un numero (come ho fatto nell'esempio soprastante), bisogna utilizzare una variabile constante (const)
ora che abbiamo creato il nostro array di 20 elementi, vediamo come si usa:
un array è composto dal nome (che è come dire, un nome collettivo per tutti gli elementi che racchiude) e da un indice tra parentesi quadrate. l'indice ci permette di accedere ad un determinato elemento piuttosto che ad un altro. l'indice è uno strumento molto importante che se non viene utilizzato a dovere, può dare fastidiosi problemi, ad esempio si può "sforare" dalla dimensione dell'array (cioè accedere a un elemento non presente nell'array) senza rendersene conto.
se io dichiaro un array di 20 elementi, nel modo seguente:
int variabile[20];
come devo utilizzare l'indice per accedere a tutti gli elementi? semplice!
l'indice può partire da 0 e arrivare fino a 19. vediamo come accedere ad esempio a qualche elemento del vettore dichiarato sopra.
a=variabile[0]; --> giusto. accedo al primo elemento
b=variabile[1]; --> giusto. accedo al secondo elemento
c=variabile[12]; --> giusto. accedo al tredicesimo elemento
d=variabile[19]; --> giusto. accedo al ventesimo elemento
e=variabile[25]; --> sbagliato. tento di accedere al ventiseiesimo elemento, ma nel mio vettore ce ne sono solo venti!
f=variabile[6]; --> giusto. accedo al settimo elemento
g=variabile[20]; --> sbagliato. tento di accedere al ventunesimo elemento, ma nel mio vettore ce ne sono solo venti!
in generale, se creo un array di n elementi, il mio indice dovrà avere un range che va da 0 a n-1. spero di essere stato abbastanza chiaro. ovviamente l'indice può essere sostituito da una qualsiasi variabile di tipo int che sia stata inizializzata con un numero conforme alla dimensione dell'array.
curiosità: i cicli di tipo FOR sono ottimi per lavorare con gli array, perchè normalmente questi cicli richiedono l'uso di un contatore che verrà poi usato dentro l'array. (cmq gli array funzionano anche con tutti gli altri tipi di cicli)
STRUCT
delle volte si ha bisogno di gestire diverse quantità di dati dello stesso tipo in modo semplice e veloce.. e infatti sono stati creati gli array.
cosa succede però se devo gestire quantità di dati NON dello stesso tipo? bè di certo non posso utilizzare gli array. per fortuna, qualcuno ha inventato le struct!
cosa sono le struct? le struct (strutture) sono strutture di dati di diverso tipo, sotto uno stesso nome (praticamente sono degli array più "capaci").
esempio pratico: devo gestire gli alunni di una scuola di cui voglio sapere la matricola, il numero di telefono, l'anno di nascita e l'altezza.
senza conoscere le struct, dovrei fare 5 array diversi ognuno per la cosa che voglio gestire -->
const int numerostudenti=100;
int matricola[numerostudenti];
int telefono[numerostudenti];
int anno[numerostudenti];
float altezza[numerostudenti];
bene, ora potrei gestire tutto con questi 5 array, ma devo ragionare con 5 array e non è proprio una gran bella cosa. allora come risolvo questo problema? utilizzo una struct (più precisamete un array di struct)! vediamo come. scrivo un breve programma d'esempio e poi lo commento.
Codice:
#include<iostream.h>
struct alunno
{
int matricola;
int telefono;
int anno;
float altezza;
};
int main(int argc, char **argv)
{
const dimensione=10;
alunno studenti[dimensione];
int i;
for (i=0; i<dimensione; i++)
{
cout<<"Inserire i dati dell'alunno: "<<i;
cout<<"Matricola: ";
cin>>studenti[i].matricola;
cout<<"Telefono: ";
cin>>studenti[i].telefono;
cout<<"Anno di nascita: ";
cin>>studenti[i].anno;
cout<<"Altezza: ";
cin>>studenti[i].altezza;
}
for (i=0; i<dimensione; i++)
{
cout<<"Dati dell'alunno N° "<<i;
cout<<"Matricola: "<<studenti[i].matricola;
cout<<"Telefono: "<<studenti[i].telefono;
cout<<"Anno di nascita: "<<studenti[i].anno;
cout<<"Altezza: "<<studenti[i].altezza;
}
return 0;
}
con questo codice abbiamo risolto il problema proposto. vediamo cosa fa il codice riga per riga:
Citazione:#include<iostream.h> --> includo la libreria iostream perchè così posso utilizzare le funzioni cin>> e cout<< che mi servono per leggere dati da tastiera e stampare dati sul video
--> adesso dichiaro la mia struttura (struct) denominata "alunno"
--> che contiene esattamente 4 variabili, le stesse richieste dal problema: la matricola, il telefono, l'anno di nascita e l'altezza
struct alunno
{
int matricola;
int telefono;
int anno;
float altezza;
}; --> ATTENZIONE! il punto e virgola dopo la parentesi graffa è sostanziale! va messo obbligatoriamente. ovviamente va messo solo sulle dichiarazioni di struct.
int main(int argc, char **argv) --> solita funzione main (l'inizio effettivo del programma)
{
const dimensione=10; --> dichiaro una variabile per dimensionare il mio array di struct
alunno studenti[dimensione]; --> dichiaro il mio array di struct. se ci fate caso, come tipo di dato ho usato "alunno". si avete capito bene, dopo aver dichiarato una struct come ho fatto sopra, essa diventa un vero e proprio tipo di dato da utilizzare come se fosse un int o un bool o un float
int i; --> dichiaro una variabile (che utilizzero come contatore)
for (i=0; i<dimensione; i++) --> ciclo for per scorrere gli elementi dell'array di struct
{
cout<<"Inserire i dati dell'alunno: "<<i; --> stampo a video "inserire i dati dell'alunno: x"
cout<<"Matricola: "; --> stampo a video "Matricola: "
cin>>studenti[i].matricola; --> chiedo all'utente di digitare qualcosa, che andrà a finire dentro la variabile int matricola dell'elemento i dell'array di struct.
cout<<"Telefono: "; --> stampo a video "Telefono: "
cin>>studenti[i].telefono; --> chiedo all'utente di digitare qualcosa, che andrà a finire dentro la variabile int telefono dell'elemento i dell'array di struct.
cout<<"Anno di nascita: "; --> stampo a video "Anno di nascita: "
cin>>studenti[i].anno; --> chiedo all'utente di digitare qualcosa, che andrà a finire dentro la variabile int anno dell'elemento i dell'array di struct.
cout<<"Altezza: "; --> stampo a video "Altezza: "
cin>>studenti[i].altezza; --> chiedo all'utente di digitare qualcosa, che andrà a finire dentro la variabile float altezza dell'elemento i dell'array di struct.
}
for (i=0; i<dimensione; i++) --> ciclo per scorrere tutti gli elementi dell'array
{
cout<<"Dati dell'alunno N° "<<i; --> stampo a video "Dati dell'alunno N° x"
cout<<"Matricola: "<<studenti[i].matricola; --> stampo a video "Matricola: xxxxxx"
cout<<"Telefono: "<<studenti[i].telefono; --> stampo a video "Telefono: xxxxxx"
cout<<"Anno di nascita: "<<studenti[i].anno; --> stampo a video "Anno di nascita: xxxxxxx"
cout<<"Altezza: "<<studenti[i].altezza; --> stampo a video "Altezza: xxxxxxx"
}
return 0; --> il solito return 0; richiesto dal main
}
fine. semplice no? bè insomma

pian piano ci prenderete la mano. spero di essere stato chiaro. in pratica noi abbiamo creato una struttura, un nuovo tipo di dato chiamato "alunno" che possiamo utilizzare come tutti gli altri tipo di dato. in questo caso, visto che dobbiamo gestire tutti gli alunni di una classe, invece di utilizzare tante variabili di tipo "alunno", creiamo un array di tipo "alunno", cioè il nostro array di struct.
accesso alle variabili componenti di una struct
come si accede alle variabili contenute dentro una struct? come visto dall'esempio, bisogna utilizzare l'operatore speciale . (punto)
in generale:
<nomevariabilestruct>.<nomevariabilecomponentestruct>;
nel nostro caso specifico:
studente.matricola;
curiosità: è possibile fare struct che come variabili membro hanno altre struct. in questo modo si otterrà un tipo di dato molto complesso. le struct sono belle perchè siete voi a creare il vostro tipo di dato. una struct semplice, potete visualizzarla mentalmente come se fosse una riga di una tabella (record)
QUI FINISCE LA GUIDA SUL C/C++ SEGUE ORA UNA PICCOLA APPENDICE
variabili globali e variabili locali
le variabili che abbiamo utilizzato in tutti questi esempi, sono variabili locali. più precisamente il campo di azione di una variabile è relativo alla sua dichiarazione. in poche parole, se io dichiaro una variabili all'interno del main, essa sarà accessibile solo dentro il main. se invece la dichiaro dentro una precisa funzione x, essa sarà accessibile solo dalla funzione x. se dichiaro la mia variabile dentro un ciclo, essa sarà valida (accessibile) solo all'interno del ciclo. se dichiaro la mia variabile dentro un blocco di codice (cioè dentro delle parentesi graffe) essa sarà valida solo dentro quel blocco di codice.
Tutti questi esempi riguardano le variabili locali. le variabili locali "nascono" quando le dichiarate e "muoiono" quando viene eseguita la fine di quella funzione/main/bloccodicodice/ciclo.
Le variabili globali invece, per essere tali, devono essere dichiarate come le variabili normali (locali) ma al di fuori di qualsiasi funzione/main/bloccodicodice/ciclo. esse saranno accessibili da qualsiasi parte del vostro file di codice sorgente, funzione/main/bloccodicodice/ciclo che sia.
Abusare delle variabili globali spesso è sbagliato, perchè si rischia di modificare dei valori UTILI per distrazione. infatti l'uso delle variabili globali è consigliato solamente se la variabile che dobbiamo dichiarare è costante (cioè utilizza la parola chiava const)
Come faccio allora a passare una certa informazione a una funzione senza usare le variabili globali? si utilizzano i parametri della funzione, come ho spiegato molto più sopra. approfindite la cosa da soli.
inclusione di librerie o altri file di codice sorgente
come avrete notato negli esempi completi (cioè in quegli esempi che potete schiaffare su un file e funzionano) appare quando necessario questa stringa:
#include<iostream.h>
che cos'è? bè è un istruzione che dice al compilatore di tenere presente che al vostro codice sorgente va aggiunga la libreria iostream. durante la fase di linking (che è quella successiva alla fase di compilazione), il "linker" prenderà il codice contenuto in quella libreria e lo aggiungerà al vostro codice oggetto (cioè il codice sorgente dopo che è stato compilato) per farne un unico file. il file finale. l'esecutivo (.exe)
durante la stesura dei vostri programmi, potreste aver bisogno di inserire più di un file nel vostro programma (specialmente se state sviluppando un gioco).
esempio: devo fare un programma che gestisce il mio bilancio familiare. dovrei anche scrivermi le varie funzioni per calcolare l'iva, l'irpef, l'ici, e stronzate varie. come faccio? scrivo le mie funzioni in un file a parte che poi "importo" tramite il comando
#include<nomefile>
dentro il mio programma. in questo modo, quando dovrò fare un nuovo programma, ad esempio un programma che gestisce la pizzeria di ninetto il pizzettaro, potrò riutilizzare le mie funzioni già scritte, utilizzando di nuovo il comando #include<nomefile>
alcune volte però invece delle parentesi angolari (<>) noterete delle "" (virgolette). perchè?
semplice!
se io scrivo
#include "nomefile"
oltre al nome del file (con relativa estenzione) devi scrivere anche il percorso relativo al file in cui sto facendo l'include.
se io invece scrivo con le parentesi angolari
#include <nomefile>
significa che questo benedetto file deve essere cercato nella cartella di default del compilatore che contiene le varie librerie.
QUINDI:
parentesi angolari <> per i file di librerie
virgolette "" per i vostri file sorgenti contenti funzioni, struct, classi e chi più ne ha più ne metta
la spiegazione che ho fatto è un po' contorta e abbastanza spartana. consiglio di studiare su una guida seria.
altre informazioni sulla dichiarazione delle variabili
non l'ho spiegato subito, perchè non è necessariamente vitale alla programmazione ma è utile in quanto fa risparmiare righe di codice.
si possono dichiarare molteplici variabili tutte dello tipo su una sola riga!!!
ecco alcuni esempi di rapida comprensione:
int i;
int a;
int var1;
int x;
int pippo;
int array[11];
può diventare, in una sola riga:
int i, a, var1, x, pippo, array[11];
bè il risparmio è notevole no? ho risparmiato di scrivere 5 volte int! con conseguente rilassamento della mia mano destra
Stringhe
il c/c++ non ha supporto nativo per le stringhe. sono state create successivamente delle classi per implementare il supporto, ma per quello che dobbiamo fare noi, non ci servono poi a granchè (almeno che uno non debba fare un programma che confronti delle stringhe..).
Come si "crea" una stringa in c/c++? bè a pensarci bene, una stringa non è altro che una sequenza ordinata di caratteri. e noi abbiamo il tipo di dato char.. quindi una stringa in c/c++ è rappresentabile come un array di char! vediamo come.
dichiarazione e inizializzazione di una stringa:
char stringa[20]="sono una stringa";
array multidimensionali
si possono creare anche array multidimensionali.. ovvero array di array di array di array di ...
come? ah è semplicissimo.
int array[10][10];
ora ho fatto un array di array di int. cioè un array a 2 dimensioni. che sarebbe poi una matrice.. esattamente 10x10 (10 righe, 10 colonne).
inutile dire che per gestire tutti gli elementi di questo array a 2 dimensioni devo usare 2 cicli (uno dentro l'altro) e 2 contatori diversi..
il massimo numero di dimensioni è.. boh! credo sia infinito. se volete provare, divertitevi!
int array[10][10][10][10][10]...[10];
ultima nota: gli array multidimensionali, non devo avere per forza lo stesso numero di elementi. es:
int array[3][10][2];
Altri argomenti che andrebbero studiati per una migliore conoscenza del linguaggio c/c++
questa parte è un elenco di argomenti più o meno interessanti, ma necessari per un aspirante programmatore c/c++. non li spiego perchè sono abbastanza complessi e sarebbe meglio apprenderli da professionisti
- passaggio di parametri nelle funzioni
- overloading delle funzioni
- Puntatori
- Allocazione dinamica della memoria
- array dinamici (new, malloc)
- lettura/scrittura file
- strutture di dati complesse: liste, alberi, grafi, pile, code
- programmazione ad oggetti (classi, derivabilità, polimorfismo)