Il linguaggio C - tdpgalilei.altervista.org · 02'2 lqw d pdlq ^ d sulqwi ³ g ´ d sulqwi ³ g ´...

15
1 IL LINGUAGGIO “C” Ogni linguaggio per computer ha bisogno di manipolare dati; Esempio: Si vogliono sommare due numeri contenuti in due celle diverse di memoria e porre il risultato in una terza locazione. Il µP assegna ad ogni cella un indirizzo rappresentato da un numero. Essendo difficile per le persone ricordare dei numeri, è consuetudine rappresentare queste locazioni di memoria con dei nomi. In questo caso il nostro problema si può così rappresentare: TOTALE = SPESA1 + SPESA2 Spesa1 0 Spesa2 1 2 3 Totale 4564 4565 Solitamente le celle di memoria contengono 8 bit, quindi in una cella è possibile memorizzare un numero compreso tra 0 e 255. Nel caso però che si voglia operare con numeri più grandi si possono usare più byte consecutivi. In C bisogna dire al programma che tipo di numeri voglio usare, scegliendo tra quelli previsti. TIPI DI DATI char : 1 byte Può rappresentare o un numero compreso tra -128 e +127 o il codice ASCII di un carattere integer: 2 byte Intero con segno compreso tra –32768 e +32767 long int: 4 byte Intero con segno tra – 2.147.483.648 e +2.147.483.647 float: 4 byte Numero decimale in virgola mobile double: 8 byte Numero decimale in virgola mobile. Se possibile è opportuno operare con i primi tre tipi essendo in questo caso più veloce l’elaborazione del programma.

Transcript of Il linguaggio C - tdpgalilei.altervista.org · 02'2 lqw d pdlq ^ d sulqwi ³ g ´ d sulqwi ³ g ´...

1

IL LINGUAGGIO “C” Ogni linguaggio per computer ha bisogno di manipolare dati; Esempio: Si vogliono sommare due numeri contenuti in due celle diverse di memoria e porre il risultato in una terza locazione. Il µP assegna ad ogni cella un indirizzo rappresentato da un numero. Essendo difficile per le persone ricordare dei numeri, è consuetudine rappresentare queste locazioni di memoria con dei nomi. In questo caso il nostro problema si può così rappresentare:

TOTALE = SPESA1 + SPESA2

Spesa1 0

Spesa2 1 2 3

Totale 4564

4565

Solitamente le celle di memoria contengono 8 bit, quindi in una cella è possibile memorizzare un numero compreso tra 0 e 255. Nel caso però che si voglia operare con numeri più grandi si possono usare più byte consecutivi. In C bisogna dire al programma che tipo di numeri voglio usare, scegliendo tra quelli previsti. TIPI DI DATI char : 1 byte Può rappresentare o un numero compreso tra -128 e +127 o il

codice ASCII di un carattere integer: 2 byte Intero con segno compreso tra –32768 e +32767 long int: 4 byte Intero con segno tra – 2.147.483.648 e +2.147.483.647 float: 4 byte Numero decimale in virgola mobile double: 8 byte Numero decimale in virgola mobile. Se possibile è opportuno operare con i primi tre tipi essendo in questo caso più veloce l’elaborazione del programma.

2

DICHIARAZIONI DI VARIABILI Nell’esempio di apertura avremmo potuto porre int spesa_1; // Spesa_1 è un intero a 16 bit int spesa_2; // Spesa_2 è un intero a 16 bit long totale; // Totale è un intero a 32 bit

Da notare ; che deve sempre essere alla fine di ogni statement

COMMENTI Due modalità: Commento su una singola riga //Questo è un commento Commento su più righe Iniziano con /* e terminano con */ .Tutto quello che è compreso tra questi due simboli è considerato commento. Esempio /* Questo è un commento */ /* Anche questo è un commento */ NOTE Il simbolo */ di fine commento è obbligatorio

Al termine di un commento non si deve mettere ;

ARRAY Capita spesso che un insieme di dati si riferisca ad un unico argomento, ad esempio l’insieme dei voti di Piero o l’insieme dei nomi degli studenti della 2° AMEE. Si potrebbe assegnare ad ogni dato un nome, ma questo renderebbe meno agevole capire che si tratta di dati correlati tra loro e, nel caso di molti studenti o di molte classi, farebbe proliferare un numero enorme di nomi che alla fine diverrebbero incomprensibili. Per evitare tutto ciò si assegna ad un unico insieme di variabili correlate tra loro un unico nome e si indicano i vari elementi dell’insieme con un numero. Questa struttura prevede il nome di ARRAY (si potrebbe rendere in italiano con MATRICE). ESEMPIO VOTI_PIERO

6 0 7 1 3 2 1 3 8 4

3

Allora: voti_piero[0] = 6 “ “ [1] = 7 oppure: 2amee[0] = “ASTI” 2amee[1] = “BATTAGLIA” Anche gli ARRAY vanno dichiarati. In particolare bisogna dichiarare il tipo di variabile che contengono e quanti elementi contengono. Esempio int voti_piero [5]; // Questo è un array di interi composto da 5 elementi.

SEMPLICE PROGRAMMA Si riprenda il primo esempio visto: totale = spesa1 + spesa2 Per prima cosa è opportuno mettere un’intestazione al programma, così da ricordarci sempre lo scopo. /************************************************ * Questo è il mio primo programma ************************************************/ Nota La cornice non è obbligatoria, ma rende più evidente il commento. È necessario poi dichiarare le variabili int spesa1, spesa2; //Nota che non è obbligatorio usare una riga per ogni variabile, ma si // possono mettere tutte insieme separate da virgole long totale; È necessario ora scrivere il programma vero e proprio. C’è da sapere che ogni programma inizia con main ( ) e deve essere tutto contenuto tra una coppia di { }: void main(void) //void è una parola chiave del C e vuol dire NIENTE {

totale = spesa1 + spesa2; print f (“% d”, totale);

} // end main Da notare PRINTF( ). È una funzione delle librerie standard del C SINTASSI: PRINTF(“stringa di controllo”, argomenti) La stringa di controllo “% d” dice che voglio stampare un numero decimale, e in particolare quello indicato dagli argomenti. Quindi PRINT F(“% d”, TOTALE) stampa il numero decimale TOTALE.

4

Nota Vi sono molte altre stringhe di controllo che vedremo più avanti. Il programma nel suo insieme si presenta pressappoco così: /*********************************************** Questo è il mio primo programma ***********************************************/ int spesa1, spesa2; long totale; //contiene la somma Main ( ) {

totale = spesa1 + spesa2; printf(“%d”, totale); /*Stampa a video il risultato*/

} /* End main */

L’ISTRUZIONE FOR Tutti i linguaggi di programmazione hanno istruzioni che dicono al programma cosa fare. Una delle più comuni, e più potenti, è il FOR. I programmi spesso devono eseguire un numero di cicli tutti uguali che differiscono solo per un indice, o qualcosa di simile. Esempio Vogliamo stampare la tabellina del 3. Per risolvere il problema vi sono molti modi possibili. MODO1 main ( ) {

printf (“1\n”); printf (“3\n”); - - - - printf (“30\n”);

} Questo metodo funziona bene, ma presenta vari inconvenienti: a) È un programma piuttosto lungo che fa una cosa piuttosto semplice. b) Se voglio scrivere la tabellina di un altro numero, devo scrivere un nuovo programma. Si può risolvere il secondo inconveniente ad esempio così:

Nota \n nella stringa di controllo di PRINTF indica che dopo la stampa si va a capo. In pratica è un carattere di ritorno_carrello. Se non ci fosse, il risultato del programma sarebbe: 136912151821242730.

5

MODO2 int a; main ( ) {

a = 3; printf (“%d ”, a*1); printf (“%d ”, a*2); - - - printf(“%d ”, a*10);

}

Il risultato che si otterrà è:

1 3 6 9 12 15 18 21 24 27 30 Se vogliamo avere un’altra tabellina, basta cambiare il valore di a, ponendo ad esempio a = 5 avremmo la tabellina del 5. MODO3 Anche l’esempio precedente è però estremamente lungo, almeno rispetto al problema da risolvere. In effetti il problema posto può essere risolto col seguente algoritmo: Si moltiplica il numero–base per un indice che varia da 1 a 10. Questo sembra effettivamente il metodo più………………………………………………………… ………………………………………………………… operazione che viene eseguita dopo ogni giro. for(i = 1; i <= 10, i ++) test eseguito ad ogni giro Inizializzazione del ciclo Tradotto semplicemente significa: al primo giro poni i = 1. Quando hai finito il giro incrementa di 1 il valore di i [ i ++ vuol dire i = i+1] e verifica se i = 10. Se no, ricomincia il giro. Esempio int a, r; main ( ) {

a = 3; for (i = 1; i <= 10; i ++) {

r = a * i; Printf (“%d “, r);

} } Nota i ++ è una tipica notazione compatta del del C. Ogni volta che viene eseguita questa istruzione la variabile i viene incrementata di 1. Esiste anche l’operatore -- che decrementa di 1

Nota La stringa di controllo “%d ” contiene uno spazio dopo %d. Questo spazio è necessario per non ottenere tutti i numeri attaccati.

Il ciclo FOR l’insieme di istruzioni comprese tra le due graffe ed è eseguito fino a che la condizione è vera. In questo esempio dopo 10 giri la condizione non è più vera e quindi “esce” dal ciclo.

6

Esempio int pippo, pluto; main ( ) {

pippo = 10; pluto = 20; pippo ++; pluto --; printf (“pippo vale %d, pluto vale %d “, pippo pluto);

} Il risultato sarà: pippo vale 11, pluto vale 19 Nota: Nella stringa di controllo di Printf vi sono due %d perché due sono le variabili (pippo e pluto) da stampare. Nota sul ciclo for Se vi è un solo statement all’interno del ciclo, le { } non sono necessarie for(x = 5; k > 0; k--) printf (“%d, “, k); //Si può scrivere anche tutto su una riga: //for(x = 5; k > 0; k--) printf (“%d, “, k); produrrà 5, 4, 3, 2, 1 Caso particolare: for(;;) { serie di istruzioni } La serie di istruzioni verrà eseguita all’infinito. Caso particolare del caso particolare: for(;;); Qui il programma si blocca perché la serie di istruzioni è vuota, cioè il sistema non fa nulla per un tempo infinito.

L’ISTRUZIONE IF-ELSE Nessun linguaggio che si rispetti è privo di questa istruzione. Permette di deviare il flusso di un programma al verificarsi di certe condizioni. Il suo modo di lavorare è il seguente:

7

se (è vera questa condizione)

allora fai questo altrimenti

fai quest’altro. La sintassi in C è: if (condizione vera) statement else statement; Nota Per statement indicheremo d’ora in poi un numero qualsiasi di istruzioni racchiuse tra due graffe { } Esempio - - - if (variabile = 3) { printf ( ); for ( ) { - - - } } else { - - - }

- -

IL CICLO WHILE È una via di mezzo tra il ciclo FOR e l’istruzione IF. In pratica esegue continuamente un certo numero di istruzioni fino a quando una certa condizione è falsa. Il suo modo di lavorare è il seguente:

mentre (questa condizione è vera) { esegui queste istruzioni }

Nota Il blocco else non è obbligatorio e quindi può anche non comparire.

8

Esempio i = 1; while (i < 10) { i ++;

printf(“%d “, i); } Il risultato è il seguente: 2 3 4 5 6 7 8 9 10 Nota È evidente che se la condizione del while è falsa ancora prima di entrare nel ciclo, questo non verrà mai eseguito. Esempio: while(3 > 4) { //fai qualcosa } non fa nulla perché, almeno per il C, 3 è minore di 4 OPERATORI RELAZIONALI Per operatori relazionali si intendono i seguenti: Esempi maggiore > if (a>3) minore < while (pippo < pluto) maggiore o uguale >= minore o uguale <= uguale = = if (3 = = pluto) diverso != Attenzione a = = L’uguale logico [ = = ] è diverso dall’uguale aritmetico; un conto è dire [pippo = 3] (in questo caso nella variabile pippo viene messo il valore 3) e un'altra cosa è [pippo = = 3] questo è un controllo logico che risulta vero se in pippo c’è il numero 3 e falso negli altri casi i+= 2 i = i+2 i-= 4 i = i+2 i*= pluto i = i * (pluto) i/= x+2 i = i/(x+2)

9

STRINGHE E CARATTERI Per stringa intenderemo sempre un’espressione qualsiasi chiusa tra apici. Esempio: “Questa è una stringa” “*+-3215*” anche questa è una stringa Le stringhe sono memorizzate all’interno del computer come codice Ascii. Esempio “PIPPO” 80 73 80 80 79 00 Attenzione: Il C alla fine di una stringa mette sempre 00 Abbiamo visto come sia possibile stampare una stringa utilizzando printf(). Vediamo ora come sia possibile attivare una variabile contenente una stringa e come sia possibile modificare o comunque operare con questa stringa. NOTA IMPORTANTE In C non esistono variabili che possono contenere stringhe. Rispetto ad altri linguaggi questa può sembrare una forte limitazione. Ad esempio in BASIC è possibile porre A$=”tutto quello che mi pare”. E’ opportuno dividere le stringhe in due gruppi: le stringhe costanti cioè che non cambiano mai durante il programma e quelle variabili. In linea di principio entrambi i tipi si possono memorizzare in array di caratteri, ma è consuetudine (ed è anche conveniente per risparmiare memoria) operare diversamente. LA DIRETTIVA #DEFINE Serve per definire all’inizio del programma le quantità costanti ,stringhe o nemeri. Esempio #define MESSAGGIO “questo è un messaggio” #define PICCOLO 3 #define GROSSO 133 int a,b; main() {

a = PICCOLO; b = GROSSO; printf(MESSAGGIO); printf(“\n%d %d,a,b);

} Il risultato sarà:

10

Questo è un messaggio 3 133

NOTA E’ consuetudine da rispettare scrivere con lettere maiuscole le quantità costanti. IMPORTANTE Il C fa distinzione tra maiuscole e minuscole: pluto è diverso da PLUTO Esempio: pluto=3 PLUTO=222 printf(“%d %d”,pluto,PLUTO) da come risultato 3 222 ARRAY DI CARATTERI Si è detto che l’unico modo di realizzare variabili di stringa è quello di utilizzare array. Si ricorda anche che il codice Ascii di A è 65, B=66 ecc… Esempio /*---------------------------------------- Riempie un array con le lettere Maiuscole dell’alfabeto -----------------------------------------*/ #define MAX_LEN 25 //Da notare questo tipico assegnamento della lunghezza #define EOF 0 //dell’array che poteva anche essere definito cosi char pippo[MAX_LEN+2] // pippo[27] int i; main() {

for(i=0;i<=MAX_LEN;i++) pippo[i]=i+65; pippo[i]=0; //Alla fine di ogni stringa è obbligatorio mettere il //simbolo di fine stringa indicato con 0 i=0; while(pippo[i]!=EOF) //EOF = 0 (guarda nei #define sopra) { printf(“%c, “pippo[i]); i++ }

} Il risultato sarà: A,B,C,…………….,X,Y,Z Nell’esempio precedente vi sono molte cose importanti da notare: 1) La dimensione dell’array deve essere obbligatoriamente definita 2) Abbiamo fissato pippo[] lungo 27 infatti sono 26 caratteri,da A a Z più lo zero finale (definito

all’inizio EOF che sta per End Of File) 3) Il carattere EOF aggiunto alla fine della stringa

11

E’ anche possibile inizializzare un array di caratteri con una stringa in sede di dichiarazione delle variabili Esempio: char messaggio[]=”Questa è una stringa”; In questo modo si è risolto sia il problema di inizializzare l’array sia quello di definire le lunghezze dell’array che viene calcolata dal compilatore, il quale si cura anche di mettere in fondo il carattere di fine stringa(0) INIZIALIZZAZIONE DI VARIABILI Già si è visto come definire quantità costanti con #DEFINE. In C è indispensabile inizializzare tutte le variabili ad un valore certo prima di utilizzarle,questo perché altrimenti non sappiamo quanto potrebbero valere al loro primo utilizzo. L’inizializzazione può avvenire sia all’inizio del programma Esempio: main() {

int a,b,c;

a=3; b=2; c=0;

} Sia, ed è cosa comune, in fase di dichiarazione int a=3; float b=5*3 E-2 Interessante è l’inizializzazione delle variabili char. Ricordando che rappresentano un singolo byte di memoria esse possono rappresentare numeri da 0 a 255,oppure con caratteri del set Ascii. In questo caso nel byte di memoria conterrà la codifica Ascii Esempio: char a=65; char b=’A’; //Attenzione:l’apice è singolo non doppio come quello delle stringhe In questo esempio a e b contengono lo stesso numero, essendo 65 il codice Ascii di A. NOTA L’uso dei singoli apici produce sempre un valore equivalente al valore numerico del codice Ascii. E’ cosi possibile fare operazioni del tipo: a=’A’-60; /*In questo caso in a verrà posto il valore 5 */

12

Alcuni caratteri non grafici possono essere rappresentati con le sequenze della seguente tabella ‘\n’ new-line ‘\t’ tab orrizzontale ‘\b’ back-space ‘\r’ ritorno carrello (senza nuova linea) ‘\\’ back-slash (il carattere \) ‘\’’ apice singolo ‘\0’ carattere NULL (codice Ascii = 0) è il carattere di fine stringa INIZIALIZZAZIONE DI ARRAY Esempio: int x[]={1,3,5}; //Crea un array di interi composto da 3 membri float y[4][3]= //Crea un array di 4 righe e 3 colonne. Essendo

//inizializzate solo 3 righe,l’utima viene messa a 0 { {1,3,5}; {2,4,6}; 1 3 5 {3,5,7}; 2 6 4 }; 3 5 7 0 0 0 Si può ottenere lo stesso risultato precedente con float y[4][3]={1,3,5,2,4,6,3,5,7}; oppure con float y[4][3]={1,3,5,

2,4,6, 3,5,7};

Char a[4][3]= { {1},{2},{3},{4} 1 0 0 }; 2 0 0 3 0 0 4 0 0 char messaggio[]=”Questa è una inizializzazione”; NOTA: In questo caso il compilatore aggiunge in fondo ‘\0’ come fine stringa

13

FUNZIONI Le funzioni sono la parte più importante e caratteristica del C, è quindi fondamentale conoscerle perfettamente. Una funzione è l’equivalente delle subroutines o delle procedure degli altri linguaggi. Essa costituisce un utile modo per relegare certi calcoli in una scatola nera che può essere usata senza preoccuparsi di sapere cosa c’è al suo interno. Un esempio di funzione già visto è printf(). In effetti provvede a stampare sul monitor qualcosa, ma noi non ci siamo curati di sapere quali operazioni svolge esattamente. Le funzioni si possono dividere in 2 grossi gruppi: quelle di libreria, che sono fornite col compilatore (vi sono versioni di C che contengono centinaia o migliaia di funzioni) e quelle scritte da noi all’interno del programma. In generale una funzione è un pezzo di programma ma separato dal resto che prende un certo numero di valori di ingresso, li elabora e restituisce un risultato. VALORI DI INPUT FUNZIONE VALORI DI OUTPUT Esempio: b=30; a=sin (b) La funzione sin() prende in ingresso il valore di b, lo elabora e rende il risultato. Si voglia scrivere una funzione che esegua x elevato alla n e si chiami potenza(). Cosi potenza(2,5) è 32. Esempio: 1- main() //Questo programma scrive le prime 9 potenze del 2 2- { 3- int i; 4- for(i=0; i<10; i++) 5- printf(“2 elevato a %d=%d”,i,potenza(2,i)); 6- } 7- //fine del main //================================================================ // eleva x alla n-esima potenza // NOTA: è buona abitudine evidenziare bene le funzioni con un // commento ben visibile e chiaro //================================================================ 8- int potenza (int x,int n) 10-{ 11- int i,p; 12- p=1; 13- for(i=1; i<=n; i++) p=p*x; 14- 15- return(p); 16- 17-} 18-// end program

14

Questo programma è un condensato di regole e consuetudini. Lo analizzerò riga per riga (per questo le ho numerate) A questo proposito è necessario introdurre due concetti fondamentali: VARIABILI GLOBALI E VARIABILI LOCALI Ogni programma C si può pensare composto da 2 blocchi fondamentali: il blocco MAIN e il blocco delle funzioni. Questo ultimo a sua volta si può pensare diviso in tanti blocchi indipendenti quante sono le funzioni. PROGRAMMA MAIN FUNZIONI F1 F2… Fn In linea di massima le variabili che usa ciascun blocco e blocchetto sono valide solo al suo interno e sconosciute altrove. Queste variabili si chiamano LOCALI. A volte è però necessario avere alcune variabili conosciute ovunque: le variabili GLOBALI. In C è semplice esplicitare questo fatto: Le variabili dichiarate prima del blocco main() sono globali, quelle dichiarate all’interno dei blocchi sono locali a quelle dei blocchi. /* Esempio di dichiarazioni variabili */ int var 1,var 2 /*Queste sono globali*/ main() {

int m1,m2 /* Queste sono conosciute solo nel main */

} funzione() {

int m1,m2; /* Queste sono conosciute solo in funzione() */ } NOTA: m1 e m2 del main() sono diverse da m1 e m2 di funzione(). Anche se i nomi sono uguali il compilatore non fa confusione. ESAME DELL’ESEMPIO DELLA PAGINA PRECEDENTE 1 Il programma inizia subito con main() non ci sono variabili globali 3 i è locale al main. Si nota che ha lo stesso nome di i della funzione (riga11) ma è

evidente che sono 2 cose diverse 5 E’ una riga piuttosto complessa. C’è una printf() che chiama dal suo interno la

funzione potenza(). La riga si sarebbe potuta spezzare anche cosi: var=potenza(2,i); printf(“------“,i,var); Sono due modi leciti,ma è più usato il primo metodo,molto più compatto.

6 Il main è finito. Iniziamo le dichiarazioni delle funzioni. In questo caso è una sola perché printf() è di libreria.

15

8 E’ la definizione della funzione potenza(). Si noti che è obbligatorio dichiarare sia il tipo di risultato che rende la funzione (in questo caso INT) che i tipi delle variabili di ingresso.

10 Inizia la funzione che termina a riga 17. 11 La funzione usa 2 variabili locali. 12 P viene inizializzata. 13 Cicolo di calcolo vero e proprio. 15 Return(P) rende al programma chiamante l’output della funzione (il valore di P)

E fa uscire il flusso del programma dall’ambiente della funzione per tornare al programma chiamante che potrebbe anche non essere il main() ma un’altra funzione.

17 Fine della funzione.