Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

40
Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone

Transcript of Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Page 1: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Introduzione alla programmazione con linguaggi di alto livello

-- Introduzione al C --

Introduzione alla programmazione con linguaggi di alto livello

-- Introduzione al C --

Vito Perrone

Page 2: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Indice

•Obiettivi della programmazione in linguaggi di alto livello

•La macchina astratta C

•Struttura di un programma C

• Istruzioni principali del C

•Primi, semplici, esempi

•Primi esempi … un po’ meno semplici

Page 3: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Obiettivi della programmazione in linguaggi di alto livello (1)

• E’ meglio questo:0 READ1 STORE 1012 LOAD= 03 STORE 1024 LOAD 1015 BEQ 136 READ7 ADD 1028 STORE 1029 LOAD 10110 SUB= 111 STORE 10112 BR 413 LOAD 10214 WRITE15 END

Page 4: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Obiettivi della programmazione in linguaggi di alto livello (2)

• O questo:READSTORE CONTATORELOAD= 0STORE SOMMA

CICLO_SOMMA: LOAD CONTATOREBEQ STAMPA_FINALEREADADD SOMMASTORE SOMMALOAD CONTATORESUB=1STORE CONTATOREBR CICLO_SOMMA

STAMPA_FINALE: LOAD SOMMAWRITEEND

Page 5: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Obiettivi della programmazione in linguaggi di alto livello (3)

• Altri aspetti “sgradevoli” del linguaggio di von Neumann :“Esegui (a+b)*(c+d)” LOAD A

ADD B

STORE TEMP

LOAD C

ADD D

MULT TEMP

“RIPETI LA SEQUENZA DI OPERAZIONI FINCHE’ LA SEQUENZA DEI DATI NON E’ ESAURITA”

BEQ ….…..

Page 6: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

La macchina astratta (del nucleo) del C

Page 7: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Elementi -e terminologia- essenziali• Standard Input, Standard Output

• Stringa: una successione finita di caratteri (per esempio “Giorgio, ieri, alfa-beta…”. E’ immagazzinata in celle consecutive, ciascuna contenente un singolo carattere della stringa.

• Le celle di memoria vengono chiamate anche variabili ( /= dall’omonimo concetto matematico!)

• Le variabili, le istruzioni e altri elementi del programma che saranno introdotti più avanti sono indicati tramite identificatori simbolici.

• identificatore simbolico: una successione di lettere e cifre, in cui al primo posto vi è una lettera. Il carattere speciale “_” viene considerato come cifra. Esempi:

• a, x, alfa, pippo, a1, xy23, Giuseppe, DopoDomani….

• Per il momento: numero di celle illimitato e ogni singola cella può contenere un qualsiasi valore numerico (sia intero sia reale) o un qualsiasi carattere

• Identificatori predefiniti e riservati (Per esempio, scanf e printf )• Parole chiave (Per comodità -di lettura umana, non del calcolatore!- le parole

chiave sono in neretto)

Page 8: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Struttura sintattica di un programma C

• Un programma C è composto da:

− un’intestazione seguita da

− una sequenza di istruzioni racchiusa tra i simboli { e }.

• L’intestazione è costituita dall’identificatore predefinito main seguito da una coppia di parentesi ( ) (per il momento vuote)

• Le istruzioni sono frasi del linguaggio di programmazione; ognuna di esse termina con il simbolo ‘;’.

Page 9: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Le principali istruzioni del C (1)

1. Istruzione di assegnamento • Assegna a una variabile il valore di un’espressione

• Esempi :

• x = 23;w = 'a';y = z;r3 = (alfa*43–xgg)*(delta–32*ijj);x = x+1;

• Se la cella a contiene il valore 45 e la cella z il valore 5, l’istruzione

• x = (a–z)/10• fa sì che nella cella x venga immagazzinato il valore 4.

• NB: per distinguere il valore carattere a dall’identificatore della variabile a, il primo viene indicato tra apici.

Page 10: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Le principali istruzioni del C (2)

2. Istruzioni di ingresso e uscita

• Consistono negli identificatori predefiniti scanf o printf seguiti da una coppia di parentesi che racchiude l’identificatore di una variabile.

• Determinano la lettura o scrittura del valore di una variabile dallo Standard Input o sullo Standard Output.

• Alcune comode abbreviazioni:

• printf((a–z)/10); per: temp = (az)/10; printf(temp);• dove temp denota una variabile non usata altrimenti nel programma.

• printf("alfa"); per: printf('a'); printf('l'); printf('f'); printf('a');

• differenza tra l’istruzione printf(2) e l’istruzione printf('2')?

Page 11: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Le principali istruzioni del C (3)

3. Istruzioni composte

• producono effetti diversi a seconda che siano verificate o meno certe condizioni sul valore delle variabili.

• Condizione (o espressione booleana): un’espressione il cui valore può essere vero o falso. Costruita mediante

– i normali operatori aritmetici,

– gli operatori di relazione (==, !=, <, >, <=, >=),

– gli operatori logici (!, ||, &&), corrispondenti, nell’ordine, alle operazioni logiche NOT, OR, AND.

• Esempi di condizioni:

x == 0

alfa > beta && x != 3

!((a + b)*3 > x || a < c)

Page 12: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Le principali istruzioni del C (4)

3.1 Istruzione condizionale

• costituita dalla parola chiave if, seguita da

– una condizione racchiusa tra parentesi tonde,

– una prima sequenza di istruzioni racchiusa tra parentesi graffe,

– la parola chiave else,

– una seconda sequenza di istruzioni racchiusa tra parentesi graffe.

– Il “ramo else” dell’istruzione può essere assente.

– Le parentesi graffe vengono in genere omesse quando la successione di istruzioni si riduce a un’istruzione singola.

Page 13: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

• Esempi di istruzioni condizionali:

if(x == 0) z = 5; else y = z + w*y;if(x == 0) {z = 5;} else {y = z + w*y;}if ((x+y)*(z-2) > (23+v)) {z = x + 1; y = 13 + x;}if ((x == y && z >3) || w != y) z = 5; else {y = z + w*y; x = z;}

• Istruzioni scorrette:

if (x == 0) else y = z; y = 34;if (x == 0) a; else b + c;

• Esecuzione di un’istruzione condizionale:

− La macchina valuta la condizione, Nel caso “vero” esegue solamente la prima sequenza di istruzioni,

Nel caso “falso” esegue la seconda sequenza di istruzioni.

− Se manca il ramo else e la condizione è falsa, la macchina prosegue con l’istruzionesuccessiva all’istruzione condizionale.

Le principali istruzioni del C (5)

Page 14: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

3.2 L’istruzione iterativa (ciclo o loop).• Permette la ripetizione dell’esecuzione di una sequenza di istruzioni ogni volta

che una certa condizione è verificata.

• È costituita dalla parola chiave while, seguita dalla condizione e da una sequenza di istruzioni fra parentesi graffe (detta corpo del ciclo).

• Esempi:

while (x >= 0) x = x – 1;while (z != y) {y = z – x; x = x*3;}

• Esecuzione di un’istruzione iterativa:– Valutazione della condizione

– Se questa è falsa non viene eseguito il corpo del ciclo e si passa direttamente all’istruzione successiva.

– Altrimenti si esegue una prima volta il corpo del ciclo; si valuta ancora la condizione e, nuovamente, si esegue il corpo del ciclo se essa è risultata vera. Quando la condizione risulta falsa si esce dal ciclo, ovvero si passa all’istruzione successiva all’istruzione iterativa. Il ciclo viene ripetuto finché la condizione rimane vera.

Le principali istruzioni del C (6)

Page 15: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

• Alcune osservazioni:

• In un’istruzione ciclica, l’esecuzione potrebbe non terminare mai!– L’istruzione condizionale e l’istruzione iterativa sono dette istruzioni composte perché esse sono costruite componendo istruzioni più semplici;

– Molto utile per la costruzione di programmi complessi

– Un’istruzione composta può contenere al suo interno una qualsiasi altra istruzione, eventualmente essa stessa composta.

• Le macchine reali sono però costruite sullo schema di von Neumann:

• Chi si occupa di “colmare il gap” tra la macchina astratta C e la macchina reale -del tipo di v.N.?

• Il software di base. Più precisamente:–il compilatore, o, più raramente,

–l’interprete

Le principali istruzioni del C (7)

Page 16: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

I primi, semplici, programmi in “quasi” C (1)

/*Programma NumeroMaggiore – prima versione */main(){

scanf(x);scanf(y);if (x > y) z = x; else z = y;printf(z);

}/

*Programma NumeroMaggiore – seconda versione */main(){

scanf(x);scanf(y);if (x > y) printf(x); else printf(y);

}

Page 17: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

I primi, semplici, programmi in “quasi” C (2)

/*ProgrammaCercaIlPrimoZero */main(){

uno = 1;scanf (dato);while (dato !=0) scanf(dato);printf(uno);

}

Page 18: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

I primi, semplici, programmi in “quasi” C (3)

/*ProgrammaSommaSequenza */main() {

somma = 0;scanf(numero);while (numero != 0){

somma = somma + numero;scanf(numero);

}printf(somma);

}

Page 19: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

I primi, semplici, programmi in “quasi” C (4)

/*Programma per la valutazione di un triangolo */main() {

/*Lettura dei dati di ingresso */scanf(X); scanf(Y); scanf(Z);

/* Verifica che i dati possano essere le lunghezzedei lati di un triangolo */

if ((X < Y + Z) && (Y < X + Z) && (Z < X + Y))/*Distinzione tra i vari tipi di triangolo */

if (X == Y && Y == Z)printf("I dati letti corrispondono a un triangolo equilatero");else

if (X == Y || Y == Z || X == Z)printf("I dati letti corrispondono a un triangolo isoscele");elseprintf("I dati letti corrispondono a un triangolo scaleno");

elseprintf("I dati letti non corrispondono ad alcun triangolo");

}

Page 20: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

• Come interpretare la seguente istruzione?

if (C1) if (C2) S1; else S2;

• Prima possibilità (l’else è attribuito all’if più esterno):

if (C1)if (C2) S1;

else S2;

• Seconda possibilità (l’else è attribuito all’if più interno):

if (C1)if (C2) S1;else S2;

• Convenzione: il primo ramo else viene attribuito all’ultimo if. Altrimenti, scriviamo esplicitamente:

if (C1) {if (C2) S1;} else S2;

Nota sull’istruzione if

Page 21: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Le variabili strutturate

• Un primo arricchimento della macchina astratta C

Page 22: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Gli array

• Un array viene identificato come qualsiasi altra variabile

• Però anche i suoi elementi sono variabili

• Ad essi si accede mediante un indice:• esempi:

scanf(s[2]);a[3] = s[1] + x;

if (a[4] > s[1] + 3) s[2] = a[2] + a[1];x = a[i];a[i] = a[i+1];a[i*x] = s[a[j+1]–3]*(y – a[y]);

• In C il primo elemento di ogni array è sempre lo 0-esimo

Page 23: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

/* Programma InvertiSequenza */main() {

indice = 0;scanf(x);while (x != '%') {

sequenza[indice] = x;indice = indice + 1;scanf(x);

}while (indice > 0){

indice = indice - 1;printf(sequenza[indice]);

}}

Programma InvertiSequenza

Page 24: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Primi esempi… un po’ meno semplici

• Sviluppo e codifica incrementali di algoritmi

• Uso dello “pseudocodice” per raffinamenti successivi

Page 25: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Dal problema…

• Lo Standard Input contiene una serie di dati relativi a delle fatture: per ogni fattura una cella dello Standard Input ne contiene l’importo e le tre successive la data di emissione, nella forma “giorno” (un numero compreso tra 1 e 31), “mese”, “anno”. Il ‘%’ è posto dopo l’anno dell’ultima fattura.

• Si vogliono stampare, nell’ordine, sullo Standard Output:– la dicitura: IMPORTI FATTURE EMESSE;

– la sequenza di tutti gli importi, nello stesso ordine di ingresso, preceduti dal carattere $;

– la dicitura: TOTALE FATTURE EMESSE;

– il totale delle fatture stesse, precedute dal carattere $;

– la dicitura: DATE DI EMISSIONE;

– la sequenza delle date di emissione, nello stesso ordine di ingresso. I tre elementi di ogni data devono essere separati da una /; alla fine di ogni data va scritto il carattere #.

Page 26: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…all’algoritmo…

1. Un primo ciclo esegue la lettura dei vari dati, quattro per volta (infatti ogni fattura è descritta da quattro elementi). Ognuno dei quattro dati letti viene memorizzato, rispettivamente, in una cella di quattro diversi array, denominati fatture, giorno, mese e anno. L’indice di ognuno di questi array viene incrementato di 1 a ogni iterazione del ciclo. Durante questo ciclo viene anche calcolato l’importo totale delle varie fatture.

2. Viene stampata la dicitura IMPORTI FATTURE EMESSE mediante un’unica istruzione printf.

3. Un primo ciclo di scrittura stampa nell’ordine tutti gli elementi dell’array fatture intercalandoli con il simbolo $.

4. Viene stampata la dicitura TOTALE FATTURE EMESSE seguita da $ e dal valore del totale precedentemente calcolato.

5. Viene stampata la dicitura DATE DI EMISSIONE.

6. Un secondo ciclo di scrittura stampa le varie terne di valori “giorno, mese, anno”, prelevandole nell’ordine dai corrispondenti array e introducendo il carattere / tra giorno e mese e tra mese e anno, e il carattere # tra l’anno della data corrente e il giorno della terna successiva.

Page 27: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice (1)/* Programma Fatture */

main() {

contatore = 0; totale = 0; scanf(dato);while (dato != '%') {

fatture[contatore] = dato; totale = totale + dato;scanf(dato); giorno[contatore] = dato;scanf(dato); mese[contatore] = dato;scanf(dato); anno[contatore] = dato;scanf(dato); contatore = contatore + 1;

}printf("IMPORTI FATTURE EMESSE");NumFatture = contatore; contatore = 0;while (contatore < NumFatture) {

printf('$'); printf(fatture[contatore]); contatore = contatore + 1;}printf("TOTALE FATTURE EMESSE"); printf('$'); printf(totale);

Page 28: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice (2)

printf("DATE DI EMISSIONE"); contatore = 0;while (contatore < NumFatture){

printf(giorno[contatore]); printf('/');printf(mese[contatore]); printf('/');printf(anno[contatore]); printf('#');contatore = contatore + 1;

}}

Page 29: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

Dal problema …

• Si vuole costruire un analizzatore di testo che sostituisca sistematicamente una parola con un’altra. Lo Standard Input della macchina abbia il contenuto seguente:

− In primo luogo è scritta (carattere per carattere) una parola (per “parola” intendiamo qui una sequenza di caratteri alfabetici); segue il carattere $; poi un’altra parola seguita dal carattere #; successivamente vi è una sequenza di parole separate tra di loro da uno spazio e chiusa da un % (cioè, dopo l’ultima parola c’è uno spazio seguito dal terminatore finale %).

• Il programma deve riscrivere su Standard Output il testo costituito dalla sequenza di parole dopo il #, sostituendo a ogni occorrenza della prima parola dello Standard Input la seconda. Se la prima parola manca, il programma deve stampare un messaggio che avverte l’utente dell’errore e sospendere l’esecuzione. Al contrario, può essere mancante la seconda parola: in tal caso si ottiene l’effetto di cancellare ogni occorrenza della prima parola; è ammesso il caso particolare che l’intero testo da riscrivere sia assente.

• NB: Possibilità di dati errati o, di condizioni eccezionali.

Page 30: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…all’algoritmo…

1. Verifica se prima del carattere $ esiste una parola. In caso negativo stampa il messaggio MANCA LA PAROLA DA SOSTITUIRE. In caso positivo procedi come segue.

2. Memorizza la prima parola del testo in un array di caratteri.

3. Memorizza la seconda parola in un altro array.

4. A questo punto fai la scansione dell’intero testo parola per parola (fino all’individuazione del carattere %).

4.1 Memorizza ogni parola in un array.4.2 Confronta la parola letta con la prima parola. Se le due

parolecoincidono, scrivi nello Standard Output la seconda parola,altrimenti scrivi la parola appena letta.

Page 31: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…a una prima parziale codifica…(1)/* Programma SostituzioneParole */

main() {

scanf(carattere);if (carattere == '$') printf("MANCA LA PAROLA DA SOSTITUIRE");else {[memorizza nell'array PrimaParola la sequenza di caratteri fino a '$'];[memorizza nell'array SecondaParola la sequenza di caratteri seguenti '$' fino a '#'];

scanf(carattere);while (carattere != '%'){[memorizza nell'array ParolaCorrente la sequenza di caratteri fino al prossimo spazio];[confronta PrimaParola con ParolaCorrente];if ([PrimaParola == ParolaCorrente])

[printf(SecondaParola)];else

[printf(ParolaCorrente)]; printf(' ');…

Page 32: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…a una prima parziale codifica…(2)

/* Programma SostituzioneParole (continuazione)*/…

/* Sia nel caso che si sia scritta la parola appena letta (ParolaCorrente), sia nel caso che si sia scritta la seconda parola al posto della prima, si scrive uno

spazio per separarla dalla parola successiva */scanf(carattere);

/* Inizia la lettura della prossima ParolaCorrente,a meno che il carattere letto non sia % */

}}

}

Page 33: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…alla codifica dei sottoproblemi (1)…

• Memorizzazione di una parola in un array,

• Scrittura di una parola

• Confronto tra due parole

Page 34: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…alla codifica dei sottoproblemi (2)…(confronto tra due parole)

if (LunghPrimaPar == LunghParCorr){

contatore = 0;while ((contatore < LunghPrimaPar) &&

PrimaParola[contatore] == ParolaCorrente[contatore]))

contatore = contatore + 1;if (contatore >= LunghPrimaPar)

printf("Le due parole coincidono");else

printf("Le due parole sono diverse");}else

printf("Le due parole sono diverse");

Page 35: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice completo (1)

/* Programma SostituzioneParole */main() {

scanf(carattere);if (carattere == '$')

printf ("MANCA LA PAROLA DA SOSTITUIRE");else {

contatore = 0;while (carattere != '$')

Page 36: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice completo (2)/* Programma SostituzioneParole (continuazione)*/

…/* Memorizzazione della prima parola */

{PrimaParola[contatore] = carattere;contatore = contatore + 1;scanf(carattere);

}LunghPrimaPar = contatore;scanf(carattere); contatore = 0;while (carattere != '#')

/* Memorizzazione della seconda parola */{

SecondaParola[contatore] = carattere;contatore = contatore + 1;scanf(carattere);

}LungSecPar = contatore;

Page 37: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice completo (3)

/* Programma SostituzioneParole (continuazione)*/…

/* Si entra ora nella fase di scansione del testo */scanf(carattere);while (carattere != '%'){

contatore = 0;while carattere != ' '

/* Memorizzazione della parola corrente */{

ParolaCorrente[contatore] = carattere;contatore = contatore + 1;scanf(carattere);

}LungParCorr = contatore;

Page 38: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice completo (4)/* Programma SostituzioneParole (continuazione)*/

…/* Si confronta la prima parola con la parola corrente */

if (LunghPrimaPar == LunghParCorr){

contatore = 0;while (contatore < LunghPrimaPar &&

PrimaParola[contatore] == ParolaCorrente[contatore])

contatore = contatore + 1;if (contatore >= LunghPrimaPar

/* Si ricopia la seconda parola */{

contatore = 0;while (contatore < LungSecPar) {

printf(SecondaParola[contatore]);contatore = contatore + 1;

}}else

Page 39: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice completo (5)

/* Programma SostituzioneParole (continuazione)*/…

/* Si ricopia la parola corrente */{

contatore = 0;while (contatore < LungParCorr) {

printf(ParolaCorrente[contatore]);contatore = contatore + 1;

}}

}else

Page 40: Introduzione alla programmazione con linguaggi di alto livello -- Introduzione al C -- Vito Perrone.

…al codice completo (6)/* Programma SostituzioneParole (continuazione)*/

…/* Si copia la Parola corrente: in questo caso le due parole sono differenti perché le

lunghezze sono differenti */{

contatore = 0;while (contatore < LungParCorr){

printf(ParolaCorrente[contatore]);contatore = contatore + 1;

}}printf(' ');

/*Sia nel caso che si sia scritta la parola appena letta (ParolaCorrente), sia nel caso che si sia scritta la seconda parola al posto della prima, si scrive uno spazio per

separarla dalla parola successiva*/scanf(carattere);

/* Inizia la lettura della prossima ParolaCorrente, a meno che il carattere letto non sia % */}

}}