linguaggio c – base tipi di dati mcd(n1, n2) = mcd(n1-n2, n2) se n1>n2 la seconda proprietà...

42
Esercitazione n. 3 Esercitazione n. 3 Linguaggio C – base Linguaggio C – base Tipi di dati Tipi di dati Queste slide sono distribuite con licenza Creative Commons Attribuzione-Non commerciale-Condividi allo stesso modo 2.5 Italia

Upload: others

Post on 25-Jul-2020

16 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazione n. 3Esercitazione n. 3

Linguaggio C – baseLinguaggio C – baseTipi di datiTipi di dati

Queste slide sono distribuite con licenza Creative Commons Attribuzione-Non commerciale-Condividi allo stesso modo 2.5 Italia

Page 2: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 2

Linguaggio C: Ripasso...

Fare riferimento alle dispense del docente...

Page 3: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 3

C/1: Resto divisione tra interi – Codice sorgente/1

/* Il programma calcola il resto di una divisione fra numeri interi.

Input: dividendo e divisore Output: valore del resto */

Page 4: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 4

C/1: Resto divisione tra interi – Codice sorgente/2

#include <stdio.h>

main(){ int dividendo, divisore, resto;

printf ("Dividendo: "); scanf ("%d", &dividendo); printf ("Divisore: "); scanf ("%d", &divisore);

resto = dividendo - (dividendo / divisore) * divisore;

/* il simbolo '/', nel caso di divisione tra variabili di tipo 'int', rappresenta la divisione INTERA (per cui, per esempio, se 'dividendo' contiene il valore 9, e 'divisore' il valore 2, il risultato della divisione intera è 4. Vedremo che nel caso di variabili 'float' il simbolo '/' rappresenta la divisione tra reali. */

printf ("Resto: %d\n", resto);}

Page 5: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 5

C/1: Resto divisione tra interi – Codice eseguibile

Come si rende eseguibile un programma C a partire dal codice sorgente?

1. Stesura del codice sorgente2. Compilazione3. Esecuzione

Page 6: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 6

C/2: Verifica terna pitagorica – Codice sorgente/1

/* Verifica se una terna di numeri è pitagorica (o, meglio, se i tre numeri in input corrispondono ai cateti e all'ipotenusa di un triangolo rettangolo).

Input: valori dei cateti e dell'ipotenusa Output: messaggio che indica se la terna è pitagorica o no */

Page 7: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 7

C/2: Verifica terna pitagorica – Codice sorgente/2

#include <stdio.h>

main(){ int c1, c2, ip;

printf ("Misura del primo cateto: "); scanf ("%d", &c1); printf ("Misura del secondo cateto: "); scanf ("%d", &c2);

printf ("Misura dell'ipotenusa: "); scanf ("%d", &ip);

if (c1*c1+c2*c2 == ip*ip) { printf ("Il triangolo è rettangolo\n"); } else { printf ("I valori inseriti non corrispondono a un triangolo rettangolo\n"); }}

Page 8: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 8

C/3: Verifica equidistanza – Codice sorgente/1

/* Date le coordinate x e y di 3 punti, verificare se i punti 2 e 3 sono equidistanti dal punto 1 (quindi se i punti 2 e 3 si trovano su una circonferenza con centro nel punto 1). La verifica viene fatta controllando se i quadrati delle distanze 1-2 e 1-3 sono uguali.

Input: coordinate x ed y dei 3 punti Output: messaggio che indica se i punti sono equidistanti oppure no */

Page 9: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 9

C/3: Verifica equidistanza – Codice sorgente/2

#include <stdio.h>

main(){ float x1, y1, x2, y2, x3, y3; float distq12, distq13;

printf ("Coordinata x del punto 1: "); scanf ("%f", &x1); printf ("Coordinata y del punto 1: "); scanf ("%f", &y1);

printf ("Coordinata x del punto 2: "); scanf ("%f", &x2); printf ("Coordinata y del punto 2: "); scanf ("%f", &y2);

printf ("Coordinata x del punto 3: "); scanf ("%f", &x3); printf ("Coordinata y del punto 3: "); scanf ("%f", &y3);

c'è l'esigenza di gestire numeri reali

Page 10: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 10

C/3: Verifica equidistanza – Codice sorgente/3

distq12 = (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); distq13 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);

if (distq12 == distq13){ printf ("I punti 2 e 3 sono equidistanti da 1\n"); } else { printf ("I punti 2 e 3 NON sono equidistanti da 1\n"); }

/* In realtà con il problema che i float sono comunque approssimazioni finite dei numeri reali, è meglio usare, nella condizione dell'if, una verifica di appartenenza a un intervallo, invece che l'uguaglianza semplice. Una condizione migliore quindi è

if (distq12-distq13<TOL && distq12-distq13>-TOL)

dove TOL sarà una costante definita all'inizio del file come, per esempio

#define TOL 0.0001 */}

Page 11: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 11

C/4: Calcolo circonferenza – Codice sorgente/1

/* Dato il raggio di una circonferenza, calcolare il valore di circonferenza ed area.

Input: raggio Output: circonferenza ed area*/

Page 12: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 12

C/4: Calcolo circonferenza – Codice sorgente/2#include <stdio.h>

main(){ const double pi = 3.141592;

/* La costante potrebbe anche essere dichiarata con una define: #define PI 3.141592 però le due cose sono diverse. Da una parte ho una cella di memoria (pi) che contiene un valore, che però è costante, per cui se tento di fare pi = 4; a runtime (NON ALLA COMPILAZIONE) ho un errore. Dall'altra invece viene semplicemente effettuata, IN FASE DI COMPILAZIONE, una sostituzione tra l'identificatore PI ed il valore 3.141592. PI NON corrisponde a una cella di memoria, per cui se tento di fare PI = 4 ho un errore IN FASE DI COMPILAZIONE.

(Nota: il fatto che abbia chiamato la cella di memoria costante con lettere minuscole (pi) ed invece l'identificatore usato nella define con lettere maiuscole è PURA CONVENZIONE, potevo fare l'inverso, o chiamarli entrambi alla stessa modo.) */

c'è l'esigenza di gestire numeri realiin doppia precisione

Page 13: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 13

C/4: Calcolo circonferenza – Codice sorgente/3

double raggio, area, circonf;

printf ("Raggio della circonferenza: "); scanf ("%lf", &raggio);

circonf = 2*pi*raggio; area = pi*raggio*raggio;

printf ("Circonferenza: %lf\nArea: %lf\n", circonf, area);

}

Page 14: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 14

C/5: Calcolo potenza – Codice sorgente/1

/* Data una base ed un esponente, calcolare base elevato ad esponente. Sia la base che l'esponente sono valori interi.

Input: base, esponente (deve essere >0) Output: base elevato ad esponente*/

Page 15: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 15

C/5: Calcolo potenza – Codice sorgente/2

#include <stdio.h>

main(){ int base, esp, i, ris;

printf ("Base: "); scanf ("%d", &base);

printf ("Esponente (>0): "); scanf ("%d", &esp);

if (esp < 0) { printf ("Errore: l'esponente deve essere > 0\n"); } else {

ris = 1; i = 0;

while (i < esp) { ris = ris * base; i = i+1; } printf ("Risultato base^esponente = %d\n", ris); }}

Page 16: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 16

C/5.1: Calcolo potenza (con for) – Codice sorgente/1

/* data una base ed un esponente, calcolare base elevato ad esponente. Sia la base che l'esponente sono valori interi.

Utilizzare la struttura di controllo “for”

Input: base, esponente (deve essere >0) Output: base elevato ad esponente*/

Page 17: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 17

C/5.1: Calcolo potenza (con for) – Codice sorgente/2

/* A livello sintattico, il costrutto for è costituito da:

- la parola chiave for seguita da - un coppia di () comprendente tre espressioni separate dal carattere “;” (valore iniziale della variabile di conteggio, espressione booleana sulla variabile di conteggio, incremento della variabile di conteggio). Queste sono seguite da - una qualsiasi istruzione oppure una sequenza di istruzioni racchiuse tra {}*/

Page 18: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 18

C/5.1: Calcolo potenza (con for) – Codice sorgente/3

#include <stdio.h>

main(){ int base, esp, i, ris;

printf ("Base: "); scanf ("%d", &base);

printf ("Esponente (>0): "); scanf ("%d", &esp);

if (esp < 0){ printf ("Errore: l'esponente deve essere > 0\n"); } else {

ris = 1;

/* Con l'uso del ciclo for invece del ciclo while */

for (i=0; i<esp ; i=i+1){ ris = ris * base; }

Page 19: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 19

C/5.1: Calcolo potenza (con for) – Codice sorgente/4

/* Altri modi per scrivere i=i+1: i+=1 i++ (il valore viene prima utilizzato e poi incrementato) ++i (il valore viene prima incrementato e poi utilizzato) Quindi attenzione perchè i++ e ++i NON SONO la stessa cosa! In questo caso avrebbero lo stesso effetto, ma in altri no! Per esempio, potrei scrivere la condizione del while (e quindi lo statement di mezzo del for) come

i++<esp

questo è corretto, mentre la scrittura

++i<esp

non lo è, crea confusione! Notate come scrivere

while(i++<esp){ ris*=base; }

sia in effetti molto più compatto di quanto scritto prima, ma, in compenso, sia già meno leggibile.

Altro modo per scrivere ris = ris * base: ris*=base

Notare come il C può essere compatto (e quindi illeggibile!) */

Page 20: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 20

C/5.1: Calcolo potenza (con for) – Codice sorgente/5

/* Forma classica per scrivere quel ciclo for: for (i=0 ; i<esp ; i++){ ... }

Domanda: cosa fa il ciclo while (); ??????

E il ciclo for (;;); ?????? */

printf ("Risultato base^esponente = %d\n", ris); }}

Page 21: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 21

C/6: Calcolo MCD con Euclide – Codice sorgente/1

/* Il programma calcola il massimo comun divisore tra due numeri n1 e n2, usando l'algoritmo di Euclide.

Il principio di funzionamento dell'algoritmo è il seguente: MCD(n1, n2) = n1 (o n2) se n1 = n2 MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2

la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche un divisore di n1-n2. Infatti esistono degli interi positivi d ed r per cui n1=k*d e n2=k*r. Dunque n1-n2=k(d-r) con d-r>0 2) si può dimostrare che se k è divisore comune a n1-n2 e n2, k è anche divisore di n1 3) dunque tutti i divisori comuni di n1 e n2 coincidono con i divisori comuni di n1-n2 e n2; quindi anche i massimi divisori comuni tra le due coppie di numeri coincidono

Input: numeri di cui calcolare il MCD Output: MCD dei numeri*/

Nota: risolvere in autonomia

Page 22: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 22

C/6: Calcolo MCD con Euclide – Codice sorgente/2

#include <stdio.h>

main(){ unsigned int n1, n2;

printf ("Inserire il primo numero positivo: "); scanf ("%u", &n1);

printf ("Inserire il secondo numero positivo: "); scanf ("%u", &n2);

while (n1 != n2){ if (n1>n2){ n1 = n1 - n2; } else { n2 = n2 - n1; } }

printf ("Il massimo comun divisore e': %u\n", n1);}

Page 23: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 23

C/7: Calcolo massimo di una sequenza – Codice sorgente/1

/* Data una sequenza di interi positivi, terminata dal valore 0, calcolare il massimo della sequenza.

Input: sequenza di interi positivi Output: massimo della sequenza*/

Nota: risolvere in autonomia

Page 24: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 24

C/7: Calcolo massimo di una sequenza – Codice sorgente/2

#include <stdio.h>

main(){ unsigned int curr, max = 0;

printf ("Inserire il prossimo numero positivo (0 per terminare): "); scanf ("%u", &curr);

while (curr != 0) { if (curr > max){ max = curr; }

printf ("Inserire il prossimo numero positivo (0 per terminare): "); scanf ("%u", &curr);

}

printf ("Il numero massimo inserito e': %u\n", max); }

Page 25: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 25

C/7.1: Calcolo massimo di una sequenza (do ... while) – Codice sorgente/1

/* Data una sequenza di interi positivi, terminata dal valore 0, calcolare il massimo della sequenza.

Utilizzare la struttura di controllo “do ... while”

Input: sequenza di interi positivi Output: massimo della sequenza*/

Nota: risolvere in autonomia

Page 26: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 26

C/7.1: Calcolo massimo di una sequenza (do ... while) – Codice sorgente/2

/* La sintassi della struttura di controllo do ... while è la seguente:

- la parola chiave do, seguita da - una qualsiasi istruzione oppure una sequenza di istruzioni racchiuse tra {}, seguita da - la parola chiave while seguita dall'espressione di verifica della condizione di uscita dal ciclo, racchiusa tra ()

Nota: a differenza di while e for, il ciclo interno viene eseguito almeno una volta*/

Page 27: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 27

C/7.1: Calcolo massimo di una sequenza (do ... while) – Codice sorgente/3

#include <stdio.h>

main(){ unsigned int curr, max = 0;

/* Questa è una versione più compatta del programma precedente. Poiché il ciclo di lettura DEVE essere eseguito almeno una volta, si può usare, invece del ciclo 'while' classico, la versione

seguente: do ... while */

do {

printf ("Inserire il prossimo numero positivo (0 per terminare): "); scanf ("%u", &curr);

if (curr > max){ max = curr; }

} while (curr != 0);

printf ("Il numero massimo inserito e': %u\n", max); }

Page 28: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 28

C/7.2: Calcolo massimo di una sequenza (anche numeri negativi) – Codice sorgente/1

/* Data una sequenza di interi (anche negativi), terminata dal valore 0, calcola il massimo della sequenza.

Input: sequenza di interi (anche negativi) Output: massimo della sequenza*/

Nota: risolvere in autonomia

Page 29: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 29

C/7.2: Calcolo massimo di una sequenza (anche numeri negativi) – Codice sorgente/2

#include <stdio.h>#include <limits.h>

main(){ int curr, max = INT_MIN;

/* In questo caso si sfrutta il fatto che gli int abbiano un limite inferiore per inizializzare la variabile 'max', quindi si possono utilizzare gli interi invece degli unsigned. Notare che se il primo numero che viene inserito è lo 0 allora viene stampato il valore di INT_MIN. */

printf ("Inserire il prossimo numero (0 per terminare): "); scanf ("%d", &curr);

while (curr != 0) { if (curr > max) { max = curr; }

printf ("Inserire il prossimo numero (0 per terminare): "); scanf ("%d", &curr); } printf ("Il numero massimo inserito è: %d\n", max); }

Page 30: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 30

C (e altri linguaggi): Sicurezza /1

Se occorre costruire una recinzione di 100 metri con paletti di sostegno distanziati di 10 metri, quanti paletti sono necessari?

10?

11!

Tipico errore “off-by-one”

Page 31: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 31

C (e altri linguaggi): Sicurezza /2

Nel marzo del 2002 il cosiddetto “OpenSSH Channel Code Off by One Privilege Escalation” mette in serio pericolo i server connessi in rete che utilizzano OpenSSH (dalla versione 2.0 alla versione 3.0.2) permettendo a qualsiasi utente remoto di essere autenticato come amministratore.

Il codice includeva la seguente istruzione:

if (id < 0 || id > channels_alloc)

che avrebbe dovuto essere:

if (id < 0 || id >= channels_alloc)

Page 32: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 32

Tipi di dati del linguaggio C: Ripasso...

Sono già stati utilizzati alcuni tipi di dati del linguaggio C

➢ int (unsigned int): per rappresentare numeri interi➢ float: per rappresentare numeri reali➢ double: per rappresentare numeri reali in precisione

doppia

Introduciamo un nuovo tipo di dato semplice:

➢ char: per rappresentare i caratteri alfanumerici (lettere, numeri e una serie di simboli)

Page 33: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 33

Nota: il codice ASCII

032 0x20 056 0x38 8 080 0x50 P 104 0x68 h 033 0x21 ! 057 0x39 9 081 0x51 Q 105 0x69 i 034 0x22 " 058 0x3a : 082 0x52 R 106 0x6a j 035 0x23 # 059 0x3b ; 083 0x53 S 107 0x6b k 036 0x24 $ 060 0x3c < 084 0x54 T 108 0x6c l 037 0x25 % 061 0x3d = 085 0x55 U 109 0x6d m 038 0x26 & 062 0x3e > 086 0x56 V 110 0x6e n 039 0x27 ' 063 0x3f ? 087 0x57 W 111 0x6f o 040 0x28 ( 064 0x40 @ 088 0x58 X 112 0x70 p 041 0x29 ) 065 0x41 A 089 0x59 Y 113 0x71 q 042 0x2a * 066 0x42 B 090 0x5a Z 114 0x72 r 043 0x2b + 067 0x43 C 091 0x5b [ 115 0x73 s 044 0x2c , 068 0x44 D 092 0x5c \ 116 0x74 t 045 0x2d - 069 0x45 E 093 0x5d ] 117 0x75 u 046 0x2e . 070 0x46 F 094 0x5e ^ 118 0x76 v 047 0x2f / 071 0x47 G 095 0x5f _ 119 0x77 w 048 0x30 0 072 0x48 H 096 0x60 ` 120 0x78 x 049 0x31 1 073 0x49 I 097 0x61 a 121 0x79 y 050 0x32 2 074 0x4a J 098 0x62 b 122 0x7a z 051 0x33 3 075 0x4b K 099 0x63 c 123 0x7b { 052 0x34 4 076 0x4c L 100 0x64 d 124 0x7c | 053 0x35 5 077 0x4d M 101 0x65 e 125 0x7d } 054 0x36 6 078 0x4e N 102 0x66 f 126 0x7e ~ 055 0x37 7 079 0x4f O 103 0x67 g

Page 34: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 34

C/8: crittografia - Problema

Si vuole realizzare un programma che dato un carattere in ingresso, lo trasforma in un altro carattere, che si trova OFFSET posizioni più avanti nell'alfabeto (per esempio con OFFSET = 4, il carattere 'a' diventa 'e').

E' il cifrario di Cesare

Page 35: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 35

C/8: crittografia – Codice sorgente/1

/* Dato un carattere in ingresso, lo trasforma in un altro carattere, che si trova OFFSET posizioni più avanti nell'alfabeto (per esempio con OFFSET = 4, il carattere 'a' diventa 'e'). L'alfabeto considerato è:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Per esempio, con OFFSET = 4, la lettera 'X' diventa 'b'.

La complessità del programma sta nel fatto che nella codifica ASCII le sequenze 'A'..'Z' e 'a'..'z' (viene prima la sequenza di caratteri maiuscoli) non sono consecutive, ma tra loro c'è un altro insieme di caratteri, per cui occorre spezzare il programma in 2 “if”.

Input: un carattere da convertire Output: il carattere convertito*/

Page 36: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 36

C/8: crittografia – Codice sorgente/2

#include <stdio.h>#define OFFSET 4

main(){ char curr, new;

printf ("Inserisci il carattere alfabetico da convertire: "); scanf ("%c", &curr);

if (curr >= 'A' && curr <= 'Z') { new = curr + OFFSET; if (new > 'Z') { new = 'a' + (new - 'Z'-1); } printf ("Il nuovo carattere dopo la conversione è: %c\n", new); } else if (curr >= 'a' && curr <= 'z') { new = curr + OFFSET; if (new > 'z') { new = 'A' + (new - 'z'-1); } printf ("Il nuovo carattere dopo la conversione è: %c\n", new); } else { printf ("Non è stato immesso un carattere valido\n"); }}

Page 37: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 37

C/8.1: crittografia (do ... while) - Problema

Si vuole realizzare una variante al programma precedente in grado di continuare l'esecuzione dell'algoritmo finché vengono inseriti caratteri (la conversione viene comunque fatta un carattere alla volta).

L'uscita dal programma è prevista nel caso venga inserito un carattere al di fuori dell'alfabeto dei caratteri consentiti per la conversione.

Utilizzare la struttura di controllo “do ... while”.

Nota: esercizio da svolgere in aula

Page 38: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 38

C/8.1: crittografia (do ... while) – Codice sorgente/1/* Dato un carattere in ingresso, lo trasforma in un altro carattere, che si trova OFFSET posizioni più avanti nell'alfabeto (per esempio con OFFSET = 4, il carattere 'a' diventa 'e').

A differenza del precedente, questa versione del programma si basa su un ciclo “do..while”, per cui è possibile inserire (uno alla volta) più caratteri da convertire. Per uscire dal ciclo è sufficiente digitare un carattere non alfabetico (per esempio '1', o '%', o anche lo spazio).

L'alfabeto considerato e': ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Per esempio, con OFFSET = 4, la lettera 'X' diventa 'b'.

La complessità del programma sta nel fatto che nella codifica ASCII le sequenze 'A'..'Z' e 'a'..'z' (viene prima la sequenza di caratteri maiuscoli) non sono consecutive, ma tra loro c'è un altro insieme di caratteri, per cui occorre spezzare il programma in 2 “if”.

Input: un sequenza di caratteri da convertire Output: i caratteri convertiti*/

Page 39: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 39

C/8.1: crittografia (do ... while) – Codice sorgente/2

#include <stdio.h>

#define OFFSET 4

main(){ char curr, new;

do { printf ("Inserisci il carattere alfabetico da convertire: "); scanf ("%c%*c", &curr);

/* Perché il programma funzioni correttamente è cruciale il codice '%*c' nella stringa della scanf. La combinazione "%c%*c" obbliga la scanf a leggere 2 caratteri in input, di cui però solo il primo viene memorizzato (in questo caso nella variabile 'curr'), mentre il secondo (il carattere di 'a capo') viene eliminato. */

Page 40: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 40

C/8.1: crittografia (do ... while) – Codice sorgente/3

if (curr >= 'A' && curr <= 'Z') { new = curr + OFFSET; if (new > 'Z') {

new = 'a' + (new - 'Z'-1); } printf ("Il nuovo carattere dopo la conversione è: %c\n", new); } else if (curr >= 'a' && curr <= 'z') { new = curr + OFFSET; if (new > 'z') {

new = 'A' + (new - 'z'-1); } printf ("Il nuovo carattere dopo la conversione è: %c\n", new); } } while ((curr >= 'A' && curr <= 'Z') || (curr >= 'a' && curr <= 'z'));

}

Page 41: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 41

C – linguaggi in generale: considerazioni

La codifica dei caratteri riveste un ruolo fondamentale nelle applicazioni dell'informatica, soprattutto ora che Internet collega buona parte dei PC presenti nel mondo!

Es: http://www.cremona.polimi.it/%7etode/http://www.cremona.polimi.it/~tode/

Approfondimento: codifica UNICODE

Page 42: Linguaggio C – base Tipi di dati MCD(n1, n2) = MCD(n1-n2, n2) se n1>n2 la seconda proprietà discende da ciò: 1) se n1 > n2 e k è un divisore comune a n1 ed n2, allora k è anche

Esercitazioni di Fondamenti di Informatica – Politecnico di Milano sede di Cremona – A.A. 2010/2011 – Carlo Todeschini – [email protected] 42

C – linguaggi in generale: buona formattazione?

#include <ncurses.h>/*****************************************************/ int m[256 ] [ 256 ],a ,b ;;; ;;; WINDOW*w; char*l="" "\176qxl" "q" "q" "k" "w\xm" "x" "t" "j" "v" "u" "n" ,Q[ ]= "Z" "pt!ftd`" "qdc!`eu" "dq!$c!nnwf"/** *** */"t\040\t";c(int u , int v){ v?m [u] [v- 1] |=2,m[u][v-1] & 48?W][v-1 ] & 15]]):0:0;u?m[u -1][v]|=1 ,m[ u- 1][ v]& 48? W-1 ][v ]&15] ]):0:0;v< 255 ?m[ u][v+1]|=8,m[u][v+1]& 48? W][ v+1]&15]]):0 :0; u < 255 ?m[ u+1 ][v ]|=4,m[u+1][ v]&48?W+1][v]&15]]):0:0;W][ v]& 15] ]);}cu(char*q){ return *q ?cu (q+ 1)& 1?q [0] ++:q[0 ]-- :1; }d( int u , int/**/v, int/**/x, int y){ intY=y -v, X=x -u; int S,s ;Y< 0?Y =-Y ,s,s=- 1:( s=1);X<0?X=-X,S =-1 :(S= 1); Y<<= 1;X<<=1; if(X>Y){int f=Y -(X >>1 );; while(u!= x){f>= 0?v+=s,f-=X:0;u +=S ;f+= Y;m[u][v]|=32;mvwaddch(w,v ,u, m[u ][ v]& 64? 60: 46) ;if (m[ u][v]&16){c(u,v);; ;;; ;;; return;}} }else{int f=X -(Y>>1);; while (v !=y ){f >=0 ?u +=S, f-= Y:0 ;v +=s ;f+=X;m[u][v]|= 32;mvwaddch(w,v ,u,m[u][v]&64?60:46);if(m[u ][ v]& 16) {c( u,v ); ; return;;;}}}}Z( int/**/a, int b){ }e( int/**/y,int/**/ x){int i ; for (i= a;i <=a+S;i++)d(y,x,i,b),d(y,x,i,b+L);for(i=b;i<=b+L;i++)d(y,x,a,i),d(y,x,a+ S,i ); ;;; ;;; ;;; ;;; ; mvwaddch(w,x,y,64); ;;; ;;; ;;; prefresh( w,b,a,0,0 ,L- 1,S-1);} main( int V , char *C[ ] ){FILE*f= fopen(V==1?"arachnid.c"/**/ :C[ 1],"r");int/**/x,y,c,v=0 ;;; initscr (); Z(Z (raw () ,Z( curs_set(0),Z(1 ,noecho()))),keypad( stdscr,TRUE));w =newpad ( 300, 300 ) ; for (x= 255 ; x >=0 ;x-- ) for (y= 255 ;y>=0;y-- )m[ x][ y]= 0;x=y=0;refresh( );while ( (c= fgetc (f) )+1) {if(0||c==10|| x== 256){x=0;y++;if(y==256 )break;;} else{m[x][y]=(c =='~' ?64 : c ==32 ?0: 16) ;;x ++; }}for(x=0 ;x< 256;x++)m [x][0]=16 ,m[ x][ 255]=16;for(y=0;y< 256 ; y ++) m[0 ][y ] = 16,m[255][y] =16 ;a=b=c=0; x=y =1; do{v++;mvwaddch (w, y,x ,m[x][ y]& 32? m[x ][y ] & 16? 0| acs_map[l[m[x][y]&15]]:46 : 32);c==0163&&!(m[x][y+1]&16)?y++: 0;c == 119 &&! (m[ x][ y- 1]& 16) ?y--:0;;c ==97 &&!(m[x-1][y]&16)?x--:0;c==100&&!(m[x+1 ][ y]& 16) ? x ++:0 ;if( c== 3- 1+1 ){endwin( );; return(0) ;}x -a<5?a>S- 5?a-=S-5:(a=0):0;x -a> S-5?a<255 -S* 2?a +=S-5:(a=256-S):0; y-b<5?b>L-5?b-=L-5:(b =0) :0; y-b>L-5?b<255-L *2?b+= L-5 :(b =256-L) :0;e(x,y);if(m[x][y]&64)break;}while((c=getch())!=-1);endwin();cu(Q);printf(Q,v);}

Che cosa è?

arachnidhttp://www.de.ioccc.org/years.html#2004

The International Obfuscated C Code Contest