You are on page 1of 492

Linguaggio C:

Introduzione al linguaggio
e allambiente di lavoro Dev-C++
Universit degli Studi di Brescia
Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Perch il C?
Linguaggio ad alto livello:
- astrazione vs. linguaggio macchina
- portabilit
Efficienza
- Ad oggi, uno dei linguaggi pi utilizzati per applicazioni
embedded o che comunque richiedono efficienza
(es: controllo di sistemi industriali, sistemi real-time)
Sufficientemente semplice, ma
Base per linguaggi pi evoluti

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Nascita ed evoluzione del C


B
(K. Thompson, Bell Labs, 1970)
prime versioni di UNIX

C
(D. Ritchie, Bell Labs, 1972)
UNIX

C tradizionale
(Kernighan & Rithchie, 1978,
Il linguaggio di Programmazione C )
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

C tradizionale
(Kernighan & Rithchie, 1978,
Il linguaggio di Programmazione C )

C89
(ANSI-C)
Aggiornato
C99
Non supportato da tutti i compilatori

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Il C ed altri linguaggi
Simula 67
(comparsa degli oggetti

C++
(B. Stroustrup, Bell Labs, 80)

Java
(J. Gosling, Sun Microsystems, 90)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Linguaggio ad alto livello vs macchina


Il calcolatore rappresenta i dati (e le istruzioni) in linguaggio binario
I nostri programmi in C hanno invece una forma del tipo:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[]){
int primo, secondo, somma;
printf("Inserisci il primo numero\n");
scanf("%d",&primo);
printf("Inserisci il secondo numero\n");
scanf("%d",&secondo);
somma=primo+secondo;
printf("Somma uguale a %d\n",somma);
system("pause");
return 0;
}

Evidentemente, devono essere trasformati in linguaggio macchina


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Uso di un compilatore:
programma che traduce tutte le istruzioni di un linguaggio di alto
livello (il C) in linguaggio binario, che pu essere interpretato
dal calcolatore

programma
sorgente

compilatore

linguaggio di alto livello

Programma
oggetto o
eseguibile
linguaggio macchina

segnalazione errori

NB: programma oggetto e programma eseguibile in realt


sono due cose diverse (lo vedremo in seguito)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Linguaggio e implementazione (1)

int n, g;

scanf("%d",&primo);

LINGUAGGIO C
COMPILATORE

0
1

Prof. M. Giacomin

0101011110011001
1101011110011111
0111000000011001
1101011100011101
0110011110011001
0101000111011000
1010011110011001
0101111110000000
0101010010011001
0111000000011001
0101000111011000
0101111110000000
0101111110000000
0001111110000000

zona della
memoria che
contiene le
istruzioni

IMPLEMENTAZIONE

zona della
memoria che
contiene i dati

Elementi di Informatica e Programmazione Universit di Brescia

Linguaggio e implementazione (2)


Implementazione dipende da:
- Compilatore
- Macchina (calcolatore)
- Sistema operativo
Il C maschera i dettagli dellimplementazione, ma alcune
caratteristiche sono volutamente dipendenti dallimplementazione
Due tipi di comportamento non (completamente) definito dal C:
- Dipendente dallimplementazione
- Indefinito

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Sviluppo ed esecuzione di un programma C (forma semplificata)


Il programmatore scrive il codice
sorgente (in C) con un editor
e lo memorizza in un file

editor

programma
sorgente

Calcolosomma.c
(programma in C)

compilatore

programma
eseguibile

DATI

RISULTATI

ESECUZIONE
AL
CALCOLATORE

Calcolosomma.exe
ERRORI A TEMPO
DI COMPILAZIONE

Prof. M. Giacomin

ERRORI A TEMPO
DI ESECUZIONE

Elementi di Informatica e Programmazione Universit di Brescia

ERRORI
LOGICI

10

IDE
Integrated Development Environment: Ambiente di sviluppo integrato
> comprende una variet di strumenti coordinati per supportare il
processo di sviluppo dei programmi (creazione, traduzione,
esecuzione, test, ), tra cui:
- editor
- compilatore
- linker
- debugger
- strumenti per la gestione delle configurazioni
- analizzatori statici, strumenti per il test,
> riesce a supportare e automatizzare (parte del) proc. di sviluppo
Dev-C++: IDE per programmi C/C++
- free
- tra i pi semplici a disposizione
(ma noi ne useremo comunque solo una piccola parte!)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

Note:
Dev-C++ richiede Windows 95/98/NT/2000/XP
All indirizzo www.codeblocks.org reperibile
anche Code::Blocks, per:
- Windows 2000 / XP / Vista
- Linux (Ubuntu & Debian, 32 & 64 bits)
- Mac OS X 10.4+
Un qualunque compilatore va bene per preparare l esame
(non ci saranno domande/esercizi relative ad un compilatore
piuttosto che ad un altro)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

Installazione di Dev-C++
Scaricare il programma di installazione (vedi sito esercitazioni)
ed eseguirlo, selezionare il linguaggio per installazione ed accettare
i termini di licenza
Select type of install: scegliere full
Scegliere la directory in cui si desidera sia installato Dev-C++
(conviene lasciare quella preimpostata)
Scegliere se installarlo per tutti gli utenti o meno + FINISH
Si arriva alle finestre di configurazione:
- Scegliere il linguaggio (english forse la scelta migliore) + NEXT
- Scegliere se installare la caratteristica di completamento
automatico del codice + NEXT [NB: non necessaria per noi]
- in caso affermativo, appare un altra finestra in cui si chiede se usare
una cache per ottimizzare il processo [NB: come volete] + OK
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

Creazione di un progetto
Per usare Dev-C++ occorre creare un progetto che include tutti i
file necessari nel processo di sviluppo: non solo .c, .obj, .exe ma anche
tutti i file necessari a Dev-C++ per gestire l intero processo
Per creare un progetto:
> Menu File/New/Project
> Appare una finestra per selezionare le caratteristiche del progetto:
- tipo: console, windows, vari tipi di librerie, empty project
- linguaggio: C++, C (spuntate la casella make default language)
- nome del progetto (es. primoprogramma): corrisponder al nome
delleseguibile (es. primoprogramma.exe)
> Viene data la possibilit di selezionare la directory in cui saranno
creati tutti i file del progetto
(consiglio: per ogni progetto createvi una directory separata,
p.es. primoprogramma)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

Il progetto e i file componenti (per ora solo uno)

La finestra del file corrente: a noi interessa il main


(lunico presente) in cui scrivere il programma!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

Il progetto e i file componenti (per ora solo uno)

QUI SCRIVEREMO
IL PROGRAMMA

La finestra del file corrente: a noi interessa il main


(lunico presente) in cui scrivere il programma!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

Curiosit non soddisfatta


#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
system("PAUSE");
return 0;
}

Stampa a video
Premere un tasto per continuare
e aspetta che lutente digiti un tasto prima di continuare
Noi lo utilizziamo per fare in modo che la finestra
di esecuzione non scompaia prima che lutente abbia
potuto vedere il risultato dellesecuzione del programma!

troppo presto per spiegare il significato delle varie istruzioni...

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

Compilazione ed esecuzione
Compilazione + linking:
Menu Execute/Compile
Se tutto ok compare la scritta Done , altrimenti nella finestra in
basso compare una lista di errori (con il doppio click viene sottolineata
la riga del codice sorgente corrispondente)
Esecuzione (dopo aver compilato):
Menu Execute/Run

Salvataggio e caricamento
Per i nostri scopi, si pu salvare l intero progetto con
Menu File/Save all
Per caricare un progetto esistente:
Menu File/Open project or file
e caricare il file progetto (.dev)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Linguaggio C:
Variabili e assegnamento
e semplici comandi di I/O
Universit degli Studi di Brescia
Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio di programma C
#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int x;
Dichiarazione
int y, z;
x=4;
y=5;
z=x+y;
x=x+1;
x=x+y+z;

Istruzioni
- Terminate da ;
- Eseguite in sequenza

delle
variabili usate nel
programma

printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Variabili: concetti generali


Una variabile rappresenta uno spazio per contenere un valore
TIPO

Nome
Valore

LINGUAGGIO C

(Indirizzo)

0101011110011001
1101011110011111
Indirizzo 0111000000011001
1101011100011101
0110011110011001
0101000111011000
1010011110011001
0101111110000000
0101010010011001

Prof. M. Giacomin

IMPLEMENTAZ.

Elementi di Informatica e Programmazione Universit di Brescia

Note al lucido precedente


Caratteristiche statiche delle variabili (dal punto di vista del C)
> nome: identifica univocamente la variabile
> tipo: identifica i valori che la variabile pu assumere
e gli operatori che su di essi possono essere applicati
[P.es. esistono variabili per memorizzare valori numerici
interi, valori numerici reali, dati di una persona, ]
> indirizzo: trattato in fase pi avanzata del corso
Dal punto di vista dellimplementazione, uno spazio in memoria
con valori esclusivamente binari (che il C interpreta in base al tipo)
FOCUS sullo spazio del linguaggio C (per quanto possibile!)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Sul tipo di una variabile


Es. una variabile di tipo int
x
int spazio di memoria
per contenere un
valore intero

operatori disponibili:
=, +, -, *, ecc. ecc.

Es. una variabile di tipo studente


studente

st1
spazio di memoria per

matricola
nome
cognome
num_esami

operatori disponibili:
=, .

Per ora consideriamo solo variabili di tipo int (intere)


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Dichiarazione di variabili
Prima di essere usata, una variabile deve essere dichiarata
int x;

Tipo della variabile


Nome della variabile
Una dichiarazione pu anche dichiarare pi variabili dello stesso tipo:
int y, z;

SINTASSI GENERALE
<tipo> <identificatore>;
<tipo> <identificatore1>, <identificatore2>, ;
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

IDENTIFICATORI
Nomi usati per identificare le variabili, le funzioni, le macro
Sono sequenze di lettere, cifre e underscore tali che:
- iniziano con una lettera o lunderscore
- non sono keyword (parole riservate del linguaggio C)
Gli identificatori sono case-sensitive
Esempi
int
int
int
int

un_albero, albero1;
1albero;
un-albero;
Abete, abete;

int int;
Prof. M. Giacomin

//
//
//
//
//
//

OK
ERRATO
ERRATO (- non underscore)
CORRETTO (due variabili)
ma non raccomandabile
ERRATO (keyword)

Elementi di Informatica e Programmazione Universit di Brescia

Assegnamento di variabili
Il valore di una variabile pu essere impostato mediante
loperatore di assegnamento =
Sintassi:
<identificatore> = <espressione>;
- variabile
- costante
- costruita a partire da variabili e/o costanti
mediante operatori. Esempio: x + (3*y)
Significato delloperatore di assegnamento:
> prima lespressione viene valutata (viene calcolato un valore)
> poi il valore viene assegnato alla variabile a sinistra
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
x
int x;
int y, z;

1511

x=4;
y=5;
z=x+y;
x=x+1;
x=x+y+z;
printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
x
int x;
int y, z;

x=4;
y=5;
z=x+y;
x=x+1;
x=x+y+z;
printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
x
int x;
int y, z;

x=4;
y=5;
z=x+y;
x=x+1;
x=x+y+z;
printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
x
int x;
int y, z;

x=4;
y=5;
z=x+y;
x=x+1;
x=x+y+z;
printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
x
int x;
int y, z;

x=4;
y=5;
z=x+y;
x=x+1;
x=x+y+z;

printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
x
int x;
int y, z;

x=4;
y=5;
z=x+y;
x=x+1;
x=x+y+z;

19

printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

Operatori aritmetici per valori interi


Operatori binari:
+ addizione
* moltiplicazione
- sottrazione
/ divisione (intera!)
% resto (della divisione intera)
Operatore unario: segno negativo -

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

APPROFONDIMENTO UTILE PER IL FUTURO


x=x+1;
l-value: indica un contenitore (spazio in memoria)
contenente un valore modificabile (l: left o location)
r-value: indica proprio un valore quindi non modificabile
(r: right)
Un l-value pu essere utilizzato come r-value: viene usato il
valore in esso contenuto (estraendolo mediante copia)
Il viceversa non vero:
1 = x+1;
d un errore di compilazione
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

Inizializzazione di variabili
Nella definizione le variabili possono essere inizializzate con
un valore, assegnato loro contestualmente alla creazione
int x=3 ,y, z=5;

Osservazione utile per il futuro: inizializzazione assegnamento!


Es. 1
int x=3;

//definizione con inizializzazione

Es. 2
int x;
x=3;
Prof. M. Giacomin

// definizione
// assegnamento
Elementi di Informatica e Programmazione Universit di Brescia

17

Perch il C impone di dichiarare le variabili prima di usarle?


#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[]){
int somma;
int x, y;

somme=x+y;

Supponiamo che scriva


somme al posto di somma

In questo caso il compilatore se ne accorge ,


perch somme non stata dichiarata!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Input/Output
Torniamo al programma di esempio
#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){

x=x+y+z;
printf("Ciao mondo\n");
printf(Il valore di x %d\n, x);
system("pause");
return 0;

Ciao mondo
Il valore di x 19
Premere un tasto per
continuare

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

19

Funzione di stampa printf


printf(stringa di formato, valori da stampare);
tra doppi apici

lista di espressioni (variabili / costanti / composte)


separate dalla virgola

Effetto:
stampa la stringa di formato, che contiene caratteri comuni
e specifiche di conversione che iniziano con il simbolo % (es: %d)
i caratteri comuni vengono stampati normalmente
ad ogni specifica di conversione corrisponde unespressione
nella lista degli elementi da stampare: una specifica di conversione
provoca la stampa del corrispondente valore, dopo averlo
convertito nel formato di stampa specificato dalla specifica
di conversione stessa (es: %d per il formato decimale degli interi)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

Una sequenza speciale


rappresenta il carattere di a capo

\n

Esempio 1
printf( fuori );
printf( gioco\n );

Stampa fuorigioco e va a capo

Esempio 2
int gbarca=2;
int gmilan=2;
printf( Gran risultato\nBarcellona %d Milan %d ,gbarca,gmilan);

Stampa Gran risultato:


Barcellona 2 Milan 2
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

Funzione di acquisizione dati scanf


scanf(stringa di formato, elementi da acquisire);
tra doppi apici
contiene specifiche
di conversione

lista di variabili separate


dalla virgola, ciascuna
preceduta dal simbolo &

Es.
scanf( %d , &variabile);

La funzione scanf legge caratteri dalla tastiera e li interpreta


secondo il formato specificato dalle specifiche di conversione
(p.es. con %d si aspetta un intero decimale)
Ciascun valore cos ottenuto immagazzinato nella corrispondente
variabile della lista
Gli argomenti della lista indicano in realt indirizzi di memoria in
cui memorizzare i valori acquisiti (per questo si usa &)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

Esempio
#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int num;
int successivo;
printf("Inserisci un numero\n");
scanf("%d",&num);
successivo=num+1;
printf(Successivo a %d uguale a %d\n",num,successivo);
system("pause");
return 0;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

QUELLO CHE A VOLTE NON E CHIARO!!!


Le diverse istruzioni del C hanno compiti ben distinti, senza
mescolamenti di compiti diversi che limiterebbero la flessibilit:
- lassegnamento modifica i valori delle variabili
(e NON STAMPA NULLA)
- scanf acquisisce valori dallesterno memorizzandoli nelle
variabili (e NON STAMPA NULLA)
- printf stampa (a video, ma non solo)
Schema base per acquisire dati, elaborarli e stampare un risultato:
- acquisire i dati dallutente e memorizzarli in una o pi variabili
mediante la funzione scanf
NB: scanf NON PUO STAMPARE MESSAGGI
(p.es. Inserisci un numero intero): usare printf
- elaborare i valori nelle variabili (istruzioni di assegnamento)
- stampare il risultato (o i risultati) con la printf
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

Commenti in C
Si possono inserire commenti per spiegare alcuni dettagli del
codice: ovviamente necessario che vengano marcati affinch
il compilatore li possa ignorare
Tutto ci che tra /* e */ (anche su pi righe) un commento:
/* questo
un commento */

Quasi tutti i compilatori ammettono anche i commenti nella forma


printf( Ciao\n );

//anche questo un commento

tutto ci che segue // un commento fino alla fine della riga


(in questo caso quindi il commento non su pi righe)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

Linguaggio C
strutture di controllo:
strutture sequenziali e condizionali

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Strutture di controllo
Controllano il flusso di esecuzione delle istruzioni: quali istruzioni
devono essere eseguite sulla base dello stato di esecuzione
Tipologie di strutture di controllo:
- struttura sequenziale
- istruzioni di selezione (condizionali)
- istruzioni cicliche (iterative)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

STRUTTURA SEQUENZIALE
Istruzioni non composte
Istruzioni composte o blocchi

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Struttura sequenziale (sequenza di istruzioni)


<istruzione1>
<istruzione2>

NB: le dichiarazioni di variabili


devono precedere le altre istruzioni

<istruzione3>
...
Struttura di base del C: le istruzioni sono eseguite in sequenza
(una dopo laltra)
Due tipi di istruzioni:
- non composta - termina con un punto e virgola
- composta racchiusa tra parentesi graffe, non termina con ;
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Istruzione non composta


Esempi
;

// istruzione vuota!

<tipo> <identificatore>;

// dichiarazione variabile

<identificatore> = <espressione>;

//assegnamento

Termina con un punto e virgola


Le istruzioni non composte comprendono:
- dichiarazioni variabili
- assegnamenti
- istruzioni condizionali
- istruzioni iterative

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Istruzione composta o blocco


{ <istruzione1>
<istruzione2>
<istruzione3>
... }
Sequenza di istruzioni tra parentesi graffe senza punto e virgola
Trattata come una sorta di istruzione singola (vedi poi)
Anche in questo caso, le dichiarazioni di variabili devono
precedere le altre istruzioni

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO 1
printf(Ciao);;

Sequenza di due istruzioni:


- printf
- istruzione vuota
Ricordarsi che gli spazi e gli a capo non contano per il C!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO 2
int a=3;
{ int primo, secondo, somma;
printf("Inserisci due numeri interi\n");
scanf("%d%d",&primo,&secondo);
somma=primo+secondo;
printf("Somma uguale a %d\n",somma);
}

Sequenza di due istruzioni:


- dichiarazione di variabile (con assegnamento)
- istruzione composta

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO 3
int a=3;
{ int primo, secondo, somma;
printf("Inserisci due numeri interi\n");
scanf("%d%d",&primo,&secondo);
somma=primo+secondo;
printf("Somma uguale a %d\n",somma);
};

Sequenza di tre istruzioni:


- dichiarazione di variabile (con assegnamento)
- istruzione composta
- istruzione vuota
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO 4
{ int primo, secondo, somma;
printf("Inserisci due numeri interi\n");
scanf("%d%d",&primo,&secondo);
somma=primo+secondo;
printf("Somma uguale a %d\n",somma);
{
int a;
printf(Inserisci un numero per continuare\n);
scanf(%d, &a);
}
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

ISTRUZIONI
CONDIZIONALI

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

Istruzioni condizionali
Permettono di eseguire unistruzione (non composta o blocco)
solo se si verifica una data condizione
La condizione pu essere vera o falsa
In C, esistono diverse istruzioni condizionali

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

Struttura condizionale semplice: if


Sintassi

Semantica

if (<condiz>)
<istruzione>

<condiz> tipicamente costruita


con operatori relazionali
p.es. (a<b)
<istruzione> pu essere:
- istruzione non composta
- blocco
Prof. M. Giacomin

condiz

istruzione

- se condiz vera, esegue istruzione


- poi in ogni caso passa alle
istruzioni successive

Elementi di Informatica e Programmazione Universit di Brescia

13

ESEMPIO 1
int n;
scanf(%d, &n);

int n;
scanf( %d , &n);

n<0

if(n<0)
printf( Numero inserito negativo!\n );
printf(Ciao\n);

printf(negativo!\n);

printf(Ciao\n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

ESEMPIO 2 (VERSIONE NON CORRETTA)


printf( Inserisci et );
scanf( %d , &n);
if(n>=18)
printf( Hai %d anni , n);
printf( quindi sei maggiorenne\n );
printf( Ti saluto\n );

Il programma sintatticamente corretto (compila).


Ma cosa succede ad esempio con n=6?

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

ESEMPIO 2 (VERSIONE CORRETTA)


printf()
scanf()

int n;
printf( Inserisci et );
scanf( %d , &n);

if(n>=18)
{
printf( Hai %d anni , n);
printf( quindi sei maggiorenne\n );

printf()
printf()

n>=18

}
printf( Ti saluto\n );

printf()

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

Operatori relazionali su tipi numerici


Servono per esprimere le condizioni che riguardano numeri
==
<
<=
>
>=
!=

uguale
minore
minore o uguale
maggiore
maggiore o uguale
non uguale

ES: a==b vera se a uguale a b


ES: a<b vera se a minore di b
ES: a<=b vera se a min. o ug. a b
ES: a>b vera se a maggiore di b
ES: a>=b vera se a magg. o ug. a b
ES: a!=b vera se a diverso da b

Attenzione a non confondere:


- loperatore di assegnamento =
(si usa per assegnare un valore ad una variabile)
- loperatore di uguaglianza ==
(si usa per confrontare due valori)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

Esercizio
Scrivere un frammento di codice C che, data una variabile intera
n, la trasforma nel suo valore assoluto.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Esercizio
Scrivere un frammento di codice C che, data una variabile intera
n, la trasforma nel suo valore assoluto.
int n;

if(n <0)
n = -n;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

19

Strutture condizionali if-else


Semantica

Sintassi
if (<condiz>)
<istruzione-1>
else
<istruzione-2>

condiz

istruzione-1

istruzione-2

...

Se condiz vera viene eseguita istruzione-1, altrimenti (se falsa)


viene eseguita istruzione-2; successivamente lesecuzione
prosegue con le istruzioni successive
Anche in questo caso le istruzioni 1 e 2 possono essere blocchi
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

ESEMPIO
printf()
printf( la variabile a contiene un numero );

if(a>=0)
printf( positivo\n );
else
printf( negativo\n );

a>=0

printf
( positivo );

F
printf
( negativo );

printf( Andiamo avanti );

printf( Andiamo avanti );

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

Condizioni IF-ELSE nidificate (A)


Vogliamo stampare un messaggio specifico per ognuno dei tre casi:
1) la variabile x ha valore 1
2) la variabile x ha valore 2
3) la variabile x ha un valore diverso
if(x==1)
printf( La variabile x vale solo 1\n );
else{
if(x==2)
printf( La variabile x ha valore 2\n );
else printf( La variabile x ha valore diverso da 1 e 2\n );
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

Esempio errato
if(x==1)
printf( La variabile x vale solo 1\n );
if(x==2)
printf( La variabile x ha valore 2\n );
else printf( La variabile x ha valore diverso da 1 e 2\n );

Cosa succede quando x uguale a 1?

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

Condizioni IF-ELSE nidificate (B)


Confrontare i due esempi nei due casi:
x=-10 y=-20
e
x=5 y=10
Esempio 1
if(x>y){
if(x>=0)
printf( il maggiore x ed positivo\n );
else printf( il maggiore x ed negativo\n );
}

Esempio 2
if(x>y){
if(x>=0)
printf( il maggiore x ed positivo\n );
}
else printf( il maggiore y\n );
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

NOTA TECNICA
Nel caso di istruzioni IF-ELSE una dentro laltra , un else
si riferisce sempre allif pi vicino (privo di else)
Esempio
if(x>y)
if(x>=0)
printf( il maggiore x ed positivo\n );
else printf( il maggiore x ed negativo\n );

EQUIVALENTE A
if(x>y){
if(x>=0)
printf( il maggiore x ed positivo\n );
else printf( il maggiore x ed negativo\n );
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

Esercizio finale
Scrivere un programma che determini il massimo valore tra
quattro numeri acquisiti da tastiera.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

26

Esercizio finale
Scrivere un programma che determini il massimo valore tra
quattro numeri acquisiti da tastiera.
UNIDEA
1) Acquisisci i numeri (x, y, v, z)
2) max=x;
se(y>max) max=y;
se(v>max) max=v;
se(z>max) max=z;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

27

#include <stdlib.h>
#include<stdio.h>
int main(int argc, char *argv[]){
int x,y,v,z,max;
printf("Inserisci x\n");
scanf("%d",&x);
//lo stesso per y,v,z
max=x;
if(y>max)
max=y;
if(v>max)
max=v;
if(z>max)
max=z;
printf("Massimo = %d\n", max);
system("pause");
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

28

ERRORI TIPICI

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

29

Errori comuni nelluso di IF-ELSE


Mettere il punto e virgola subito dopo if (o else): in questo caso
listruzione che segue if listruzione vuota!!!
Esempio
printf( Inserisci et );
scanf( %d , &n);
if(n >= 18);
{printf( Hai %d anni , n);
printf( quindi sei maggiorenne\n );}
printf( Ti saluto\n );

Se n==6 esegue listruzione vuota (cio niente)!


In ogni caso stampa Hai 6 anni quindi sei maggiorenne !
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

30

Mettere il punto e virgola subito dopo un blocco nel ramo if:


in questo caso ci sono due istruzioni dopo lif e poi un else:
errore di compilazione!
Esempio
printf( Inserisci et );
scanf( %d , &n);
if(n >= 18)
{printf( Hai %d anni , n);
printf( quindi sei maggiorenne\n );};
printf( Ti saluto\n );

ALTRI ERRORI VERRANNO ESAMINATI NELLA LEZIONE


SUGLI OPERATORI
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

31

Linguaggio C
strutture di controllo:
strutture iterative

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Istruzioni iterative
Sono chiamate anche cicli
Permettono di eseguire pi volte unistruzione, o un blocco di
istruzioni, che costituisce il corpo del ciclo
Prevedono di specificare una condizione di permanenza del ciclo:
fintantoch la condizione vera viene eseguita una nuova
iterazione del ciclo (ovvero, le istruzioni nel corpo del ciclo
vengono eseguite)
Tipologie di cicli:
- cicli a condizione iniziale: while e for
- cicli a condizione finale: do-while
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Istruzione while
Sintassi

Semantica

while (<condiz>)
<istruzione>
<condiz>

<condiz> costruita tipicamente


con operatori relazionali
p.es. (i<5)
<istruzione> pu essere:
- istruzione non composta
- blocco
Prof. M. Giacomin

V
<istruzione>

- se <condiz> vera viene eseguita


<istruzione>, poi si ritorna al
controllo di condiz
- quando <condiz> diventa falsa si
passa alle istruzioni successive

Elementi di Informatica e Programmazione Universit di Brescia

Esempio
Acquisizione dallutente di un intero, continuando a ripetere linput
se lutente inserisce un numero strettamente negativo
printf( Inserire un numero maggiore o uguale a 0\n );
scanf( %d ,&n);
while(n<0)
scanf( %d ,&n);

Nota
Poich la condizione valutata allinizio del ciclo, il corpo
del ciclo potrebbe non essere mai eseguito (nellesempio, se
l utente inserisce subito un valore positivo)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Istruzione do-while: ciclo a condizione finale


Sintassi

Semantica

do
<istruzione>
while (<condiz>);

<condiz> costruita tipicamente


con operatori relazionali
p.es. (i<5)
<istruzione> pu essere:
- istruzione non composta
- blocco
Prof. M. Giacomin

<istruzione>
V

<condiz>
F
...

-Viene eseguita <istruzione>


- Se <condiz> vera viene eseguita
<istruzione> e si prosegue;
quando <condiz> diventa falsa si
passa alle istruzioni successive

Elementi di Informatica e Programmazione Universit di Brescia

Uso di do-while (1)


A differenza di while (e for), la struttura do-while un ciclo
a condizione finale: garantisce che venga eseguita sempre
almeno una iterazione del ciclo
Dal punto di vista teorico tutto ci che si pu fare con do-while
si pu fare anche con while (o for); pu essere per conveniente
usare do-while nei casi in cui il corpo del ciclo debba in ogni caso
essere eseguito almeno una volta
Vediamo un esempio

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Uso di do-while (2)


Esempio gi visto: acquisire un intero da tastiera, ripetendo
loperazione di input se l utente inserisce un numero negativo
Versione con while
printf( Inserire un numero maggiore o uguale a 0\n );
scanf( %d ,&n);
while(n<0)
scanf( %d ,&n);

Versione con do-while


printf( Inserire un numero maggiore o uguale a 0\n );
do
scanf( %d ,&n);
while(n<0);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio: while o do-while, questo il dilemma


Scrivere un programma che continua ad acquisire un intero fino
a quando lutente non inserisce un numero strettamente maggiore
di 100, dopodich lo stampa a video.
Esempio:
L utente inserisce
-100
34
49
200

Prof. M. Giacomin

A questo punto il calcolatore


stampa 200.

Elementi di Informatica e Programmazione Universit di Brescia

Un primo modo
Ovviamente, mi serve un ciclo che continui ad acquisire
numeri fino a quando il numero inserito non sia corretto
(strettamente maggiore di 100).
Dato che devo acquisire almeno un numero, posso pensare di
usare un ciclo do-while (a condizione finale)
do{
printf( Inserisci un numero strettamente maggiore di 100\n );
scanf( %d , &n);
}
while (n<=100);
printf(Numero inserito = %d\n, n);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Il programma completo
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char*argv[])


{
int n;

do{
printf("Inserisci un numero strettamente maggiore di 100\n");
scanf("%d", &n); }
while (n<=100);

printf("Numero inserito = %d\n", n);


system("PAUSE");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

Unaltra versione (cambiamo leggermente la richiesta)


Supponiamo che:
La prima volta che acquisisco un numero voglio stampare il
messaggio "Inserisci un numero strettamente maggiore di 100"
Ogni volta che lutente sbaglia, voglio inserire un messaggio
diverso, per evidenziare che ha sbagliato
acquisisci numero n (con messaggio iniziale)
while(n scorretto){
stampa messaggio di errore;
acquisisci n;
}
stampa n;
//corretto!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

Il programma completo
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char*argv[]){
int n;
printf("Inserisci un numero strettamente maggiore di 100\n");
scanf("%d", &n);
while (n<=100){
printf( Forse non mi sono spiegato bene: ");
printf( il numero deve essere strettamente maggiore di 100\n );
printf( Riprova per favore\n );
scanf("%d", &n);
}
printf("Numero inserito = %d\n", n);
system("PAUSE");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

CASI PARADIGMATICI
Alcuni esempi fondamentali che necessario comprendere
Nella pratica questi schemi vanno combinati in vario modo,
a seconda del problema da affrontare: non sono ricette semplici
da consultare e applicare pedissequamente, quindi non bisogna
impararli ma assimilarli come un gesto tecnico sportivo
(come? P.es. ricostruendoli da soli)
Saranno proposti esercizi individuali che costituiscono
varianti degli esempi successivi

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

P1: Iterazione controllata da un contatore


Quando il numero delle iterazioni noto a priori (iterazione
definita)
Una variabile, detta contatore, tiene traccia del numero
di iterazioni effettuate/da effettuare
Idea di base:
o Il contatore viene inizializzato prima del ciclo
o Ad ogni iterazione il contatore viene aggiornato
o Condizione di permanenza: si rimane nel ciclo se il contatore
indica che ci sono ancora iterazioni da effettuare

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

ESEMPIO
Stampa 10 asterischi utilizzando un ciclo
n=1;
while(n<=10){
printf(* );
n=n+1;
}

Problemi (collegati tra loro):


- come inizializzare la variabile?
- come scrivere correttamente la condizione di permanenza?
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

CONSIGLIO
Abituatevi subito a
dare un significato preciso alle variabili :
stabilire cosa rappresentano esattamente ad ogni
iterazione (quando viene controllata la condizione)
Anche se adesso sembra inutile,
meglio imparare su esempi facili
Se imparate adesso, gli esercizi desame
non saranno tanto pi difficili di questi;
altrimenti, sembreranno pi complicati di
quello che in realt sono
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

Esempio: stampare i numeri da 1 a 5


int num=1;
while(num<=5){
printf( Numero %d\n , num);
num=num+1;
}

Prof. M. Giacomin

// prossimo numero da stampare


// esci quando num > 5

Elementi di Informatica e Programmazione Universit di Brescia

17

Esempio: stampare i numeri da 1 a 5


int num=1;
while(num<=5){
printf( Numero %d\n , num);
num=num+1;
}

// prossimo numero da stampare


// esci quando num > 5 (!!!)

Variante Esempio: stampare i numeri da 1 a 5


int num=0;
while(num<5){
num=num+1;
printf( Numero %d\n , num);
}

Prof. M. Giacomin

// ultimo numero gi stampato


// esci quando num = 5 (!!!)

Elementi di Informatica e Programmazione Universit di Brescia

18

Esempio
Vogliamo stampare i numeri da 10 a 1
int n;
n=10;

// prossimo numero da stampare

while(n>=1){
printf( %d\n ,n);
n=n-1;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

19

Esempio
Scrivere un programma che acquisisce un intero positivo n
e stampa tutti i numeri pari da 2 a n.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

Esempio (continua)
Scrivere un programma che acquisisce un intero positivo n
e stampa tutti i numeri pari da 2 a n.
Soluzione
Uso un ciclo while con i che va da 2 a n (max pari<=n)
e che scandisce i numeri pari: deve essere incrementata di 2
[es: se n = 11 deve stampare 2, 4, 6, 8, 10]

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

Esempio (continua)
Scrivere un programma che acquisisce un intero positivo n
e stampa tutti i numeri pari da 2 a n.
Soluzione
Uso un ciclo while con i che va da 2 a n (max pari<=n)
e che scandisce i numeri pari: deve essere incrementata di 2
[es: se n = 11 deve stampare 2, 4, 6, 8, 10]
i=2;

// numero da stampare

while(i<=n){
printf( %d\n ,i);
i=i+2;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

Il programma completo
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char*argv[]){


int n, i;

printf("Inserisci un numero positivo\n");


scanf("%d", &n);

while(i<=n){
printf(%d\n,i);
i=i+2;
}
system("PAUSE");
return 0;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

P2: Iterazione controllata da sentinella


Per elaborare una sequenza di elementi (es: valori in input)
di lunghezza non nota a priori
Una propriet particolare degli elementi (sentinella) indica
la fine della sequenza (es: il valore 0 indica fine valori in input)
Idea di base:
o ad ogni iterazione si acquisisce e gestisce un nuovo elemento
o la condizione di permanenza controlla lelemento corrente,
uscendo dal ciclo quando la sentinella lo segnala
NB: in questo caso literazione indefinita

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

Esempio
Scrivere un programma che acquisisce una serie di numeri interi
dallutente fino a quando lutente inserisce il numero 0.
Per ogni numero acquisito (0 escluso), il programma stampa a video
il numero successivo.
ESEMPIO DI ESECUZIONE:
2
Successivo = 3
5
Successivo = 6
0
Premi un tasto per continuare
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

Variante 1
int num;

//numero acquisito da processare

printf(Inserisci la serie di numeri, 0 per terminare\n);


scanf(%d, &num);
while(num!=0){

// esce quando num = 0

(!!!)

printf(Successivo = %d\n , num+1);


scanf(%d, &num);
}

Variante 2
int num;

//numero acquisito gi processato

printf(Inserisci la serie di numeri, 0 per terminare\n);


do{
scanf(%d, &num);
if(num!=0)
printf(Successivo = %d\n , num+1);
}
while(num!=0){
Prof. M. Giacomin

// esce quando num = 0


Elementi di Informatica e Programmazione Universit di Brescia

(!!!)
26

P3: Calcolo di aggregati


Per calcolare una propriet da una sequenza di elementi tale che:
...

NUOVO
ELEMENTO

aggregatoprec
aggregato
Esempi: somma/prodotto/minimo/massimo di sequenze di valori
Idea di base:
o Si usa una variabile per laggregato inizializzata a un valore
opportuno (tipicamente: elemento neutro di una operazione
o sulla base del primo elemento delle sequenza)
o Si scandiscono gli elementi aggiornando la variabile
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

27

Esempio
Scrivere un programma che acquisisce una serie di numeri interi
dallutente fino a quando lutente inserisce il numero 0 e stampa
la somma degli elementi inseriti (se lutente inserisce subito 0,
il programma stampa 0).

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

28

int num, somma;


somma=0;

//allinizio del ciclo, indica somma numeri precedenti

printf( Inserire la sequenza di numeri, 0 per terminare\n );


do{
scanf(%d, &num);
somma=somma+num;
}
while(num!=0){
printf( La somma dei numeri inseriti %d\n", somma);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

29

Esempio
Scrivere un programma che continua ad acquisire un intero fino
a quando lutente inserisce il numero 0, quindi stampa il minimo
tra i valori inseriti (zero escluso).
Ad esempio, se l utente inserisce 10 3 4 7 2 9 9 2 0
il programma stampa 2.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

30

Primo passo: capire il testo e soprattutto il problema (se non si sa


da che parte prendere , provare a risolvere qualche
istanza a mano)
10 3 4 7 2 9 9 2 0
Se avessimo una lista lunga, non potremmo usare il
colpo d occhio : partiamo dal primo elemento e
proseguiamo a destra individuando il minimo:
10 3 3 3 2 2 2 2 0

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

31

Secondo passo: individuare un metodo risolutivo


Uso una variabile min che tiene traccia del minimo
corrente e scandisco gli elementi della sequenza
aggiornando min ad ogni elemento, fino alla fine
10 3 4 7 2 9 9 2 0
min = 10
3: 3<min, quindi min diventa 3
4: 4>min, quindi min rimane uguale (3)
7: 7>min, quindi min rimane uguale (3)
2: 2<min, quindi min diventa 2
.
Si user un ciclo per scandire la sequenza!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

32

Terzo passo: sviluppare un algoritmo


Prima bozza :
Acquisisci primo numero e assegnalo a min
Acquisisci nuovo numero
while(numero!=0){
aggiorna eventualmente min
acquisisci nuovo numero
}
stampa min
Cosa succede se l utente inserisce direttamente 0?

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

33

Seconda bozza :
Acquisisci primo numero e assegnalo a min
if(min==0) stampa messaggio di errore
else{
Acquisisci nuovo numero
while(numero!=0){
aggiorna eventualmente min
acquisisci nuovo numero
}
stampa min
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

34

NB: Conviene usare un do-while? Allinizio devo comunque


acquisire un numero e assegnarlo a min
Acquisisci primo numero e assegnalo a min
if(min==0) stampa messaggio di errore
else{
do{
acquisisci nuovo numero;
if(numero!=0)
aggiorna eventualmente min;
} while(numero!=0);
stampa min}

Ad ogni iterazione
controllo
della condizione

Entrambe le soluzioni accettabili, nel seguito while


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

35

int num, min;


printf( Inserire un numero\n );
scanf( %d ,&num);
min=num;
if(min==0)
printf( Nessun numero valido inserito\n );
else{
printf( Inserire un numero\n );
scanf( %d ,&num);
while(num!=0){
if(num<min)
min=num;
printf( Inserire un numero\n );
scanf( %d ,&num);
}
printf( Il minimo %d\n", min);
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

36

P4: Verifica esistenziale


Per verificare se in una sequenza di elementi (es: valori in input)
esiste almeno un elemento che soddisfa una certa propriet
Idea di base:
o Una variabile trovato viene inizializzata al valore 0
che indica NO (elemento non ancora trovato)
o ad ogni iterazione:
- si considera un nuovo elemento
- se lelemento soddisfa la propriet si pone trovato a 1
o Alluscita dal ciclo, trovato risulta 0 se non esiste alcun
elemento che soddisfa la propriet , 1 altrimenti

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

37

Esempio
Scrivere un programma che acquisisce una serie di numeri interi
dallutente fino a quando lutente inserisce il numero 0 e verifica
se esiste almeno un numero inserito (0 escluso) pari, stampando
un opportuno messaggio.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

38

int trovato, num;


trovato=0;

//elemento pari non trovato allinizio

printf( Inserire la sequenza di numeri, 0 per terminare\n );


scanf(%d, &num);
while(num!=0){

//num nuovo numero da processare

if(num%2==0)
trovato=1;
scanf(%d, &num);
}
if(trovato==1)
printf(Esiste un numero pari\n);
else printf(Non esiste alcun numero pari\n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

39

P5: Verifica universale


Per verificare se in una sequenza di elementi (es: valori in input)
tutti gli elementi soddisfano una certa propriet
Idea di base:
o Una variabile soddisfano viene inizializzata al valore 1
che indica SI (tutti gli elementi finora processati soddisfano)
o ad ogni iterazione:
- si considera un nuovo elemento
- se elemento NON soddisfa la propriet si pone soddisfano a 0
o Alluscita dal ciclo, soddisfano risulta 0 se non vero che tutti
gli elementi soddisfano la propriet (= esiste un elemento che
non soddisfa la propriet!), 1 altrimenti
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

40

Esempio
Scrivere un programma che acquisisce una serie di numeri interi
dallutente fino a quando lutente inserisce il numero 0 e verifica
se tutti i numeri inseriti (0 escluso) sono pari, stampando
un opportuno messaggio.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

41

int tuttipari, num;


tuttipari=1;

//allinizio tutti i numeri pari

printf( Inserire la sequenza di numeri, 0 per terminare\n );


scanf(%d, &num);
while(num!=0){

//num nuovo numero da processare

if(num%2!=0)
tuttipari=0;
scanf(%d, &num);
}
if(tuttipari==1)
printf(Tutti i numeri inseriti sono pari\n);
else printf(Esiste un numero dispari nella sequenza\n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

42

P6: Cicli con filtro


Quando in una sequenza di elementi (es: valori in input) si vogliono
elaborare solo quelli che soddisfano una certa propriet
Idea di base: si usa un if allinterno del ciclo per testare la propriet
sullelemento corrente, considerandolo solo se la propriet vera

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

43

Esempio
Scrivere un programma che acquisisce una serie di numeri interi
dallutente fino a quando lutente inserisce il numero 0 e stampa
la somma dei numeri dispari (0 se non ce ne sono).

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

44

int num, somma;


somma=0;
printf( Inserire la sequenza di numeri, 0 per terminare\n );
scanf(%d, &num);
while(num!=0){

//num nuovo numero da processare

if(num%2!=0)
somma=somma+num;
scanf(%d, &num);
}
printf(Somma numeri dispari = %d\n, somma);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

45

L istruzione iterativa for: unalternativa al while


Esempio: Stampa dei numeri da 1 a 10
con while

con for

n=1;

for(n=1; n<=10; n=n+1)

while(n<=10){

printf( %d\n ,n);

printf( %d\n ,n);


n=n+1;
}

E una sorta di while che incorpora:


- lassegnamento di una variabile contatore con un valore iniziale
- la condizione di permanenza
- laggiornamento della variabile contatore
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

46

Un altro modo di vedere le cose

n=1;
while(n<=10){

for(n=1; n<=10; n=n+1)

printf( %d\n ,n);

printf( %d\n ,n);

n=n+1;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

47

ASTRAENDO
Sintassi

Semantica

for(<ass>;<condiz>;<agg>)
<istruz>

<ass>

<ass>: assegnamento di una variabile


(contatore) con un valore iniziale
(ad esempio i=1)
<condiz> la condizione di permanenza,
tipicamente confronta il contatore con un
valore finale (ad esempio i<=5)

<condiz>

V
<istruz>

<agg> taggiornamento del contatore (es. i=i+1)

<agg>

<istruz> pu essere anche un blocco istruzioni


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

48

ESEMPIO A
Stampa numeri da 10 a 1
int n;
for(n=10; n>=1; n=n-1)
printf( %d\n ,n);

ESEMPIO B
Acquisizione di n e stampa numeri pari da 2 a n
int i, n;
scanf(%d, &n);
for(i=2; i<=n; i=i+2)
printf( %d\n ,i);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

49

Uso di for vs. while


In generale, il for offre una sintassi che risulta pi compatta
rispetto al while
Sicuramente, conviene usare il for ogni volta che viene usato una
variabile contatore per scandire il numero di iterazioni del ciclo,
tipicamente quando si conosce quante volte le istruzioni del corpo
del ciclo devono essere ripetute
Esempi:
- acquisire 100 numeri da tastiera
- acquisire n numeri da tastiera
- stampare gli elementi di un vettore (vedi lezioni successive)
- ecc. ecc.
Non comunque raro luso del for per qualsiasi tipologia di ciclo,
al posto del while (dipende anche dal gusto personale)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

50

ISTRUZIONI break e continue


Istruzione break: causa luscita immediata da un ciclo while,
dowhile, for
Istruzione continue: causa la terminazione anticipata della
corrente iterazione di un ciclo while, dowhile, for
o nel caso di ciclo for, lespressione <exp3> viene eseguita
for(n=1;n<=10;n=n+1){

for(n=1;n<=10;n=n+1){

if(n==5) break;

if(n==5) continue;

printf( %d\n ,n);

printf( %d\n ,n);


}

Stampa 1, 2, 3, 4
Prof. M. Giacomin

Stampa 1, 2, 3, 4, 6, 7, 8, 9, 10

Elementi di Informatica e Programmazione Universit di Brescia

51

Esempio
Scrivere un programma che acquisisce 10 numeri interi dallutente
e, per ogni numero acquisito, il programma stampa a video
il numero successivo. Inoltre il programma interrompe lacquisizione
(senza la stampa del successivo) se lutente inserisce il numero 0.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

52

LIDEA: gestiamo il caso tipico normalmente, il caso particolare


(uscita anticipata dallacquisizione dei 10 numeri)
con listruzione break
int i, num;
printf(Inserisci 10 numeri interi, 0 per terminare anticipatamente\n);
for(i=1; i<=10; i=i+1){

// i: indice numero da acquisire

scanf(%d, &num);
if(num==0)
break;
printf(Successivo = %d\n , num+1);
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

53

ERRORI TIPICI

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

54

Errori tipici nelluso di while (1)


Inserire una condizione di terminazione, non di permanenza
Es: per stampare i numeri da 1 a 5
int num=0;
while(num==5){
//non finch ma mentre !
num=num+1;
printf( Numero %d\n , num);
}

Dimenticare di modificare le variabili che determinano la condizione


int num=0;
while(num<5){
printf( Numero %d\n , num);
}

Prof. M. Giacomin

Ciclo infinito: manca n=n+1

Elementi di Informatica e Programmazione Universit di Brescia

55

Errori tipici nelluso di while (2)


Mettere il punto e virgola dopo while(cond): il corpo del ciclo
diventa listruzione vuota!
int num=0;
while(num<5);
NB: In
{num=num+1;
printf( Numero %d\n , num);
}

questo caso il ciclo infinito

Dimenticare le parentesi graffe nel caso di blocco con pi istruzioni


int num=0;
while(num<5)
num=num+1;
printf( Numero %d\n , num);

Prof. M. Giacomin

// Ripete solo questa!


// e stampa (solo) 5

Elementi di Informatica e Programmazione Universit di Brescia

56

Errori tipici nelluso di do-while

(1)

Inserire una condizione di terminazione al posto di quella


di permanenza
Mettere il punto e virgola dopo do
do;
scanf( %d , &n);
while(n<0);

Il compilatore segnala un errore (ci sono due


istruzioni dopo do, non trova while)

Dimenticarsi il punto e virgola dopo while


do
Il compilatore segnala un errore
scanf( %d , &n);
(dopo scanf c un costrutto while!)
while(n<0)
printf( Numero inserito=%d ,n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

57

Errori tipici nelluso di do-while

(2)

Dimenticare le parentesi graffe nel caso di blocco con pi istruzioni


do
Il compilatore segnala un errore
scanf( %d , &n);
(al posto di i=i+1; dovrebbe esserci while() )
i=i+1;
while(n<0)
printf( Numero inserito=%d ,n);

Inserire un punto e virgola dopo un blocco di istruzioni


do{
Il compilatore segnala un errore
scanf( %d , &n);
(dopo il blocco si aspetta while() )
i=i+1;
};
while(n<0)
printf( Numero inserito=%d ,n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

58

Errori tipici nelluso di for


Inserire una condizione di terminazione al posto di quella
di permanenza
Mettere il punto e virgola dopo for(;;): in questo caso il
corpo del ciclo diventa listruzione vuota
Es.
for(i=1; i<=10;i=i+1);
printf( numero %d\n , i);

In questo caso il ciclo viene ripetuto 10 volte, ma senza eseguire


alcuna istruzione! Al termine del ciclo viene eseguita listruzione
di stampa con i=11 !

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

59

Linguaggio C
Condizioni composte
(operatori logici)
Universit degli Studi di Brescia
Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Condizioni composte
Talvolta nelle strutture if, if-else, while, do-while, for
necessario specificare condizioni composte da condizioni elementari
Esempio
Scrivere un programma in linguaggio C che riceve in ingresso due
interi strettamente positivi: il programma deve ripetere lacquisizione
di entrambi i numeri finch questa condizione non sia verificata.
do{
scanf(%d, &n1);
scanf(%d, &n2);
}while(n1<=0 || n2<=0);
Prof. M. Giacomin

// || indica OR

Elementi di Informatica e Programmazione Universit di Brescia

Operatori logici
Permettono di esprimere una condizione complessa, costruita
a partire da condizioni pi semplici
Il valore di verit della condizione complessa dipende dai
valori di verit delle condizioni pi semplici
!

NOT (operatore unario)


!<cond> vera se <cond> falsa

&&

AND (operatore binario)


(<c1> && <c2>) vera se <c1> e <c2> vere entrambe

||

OR (operatore binario)
(<c1> || <c2>) vera se almeno una tra <c1> e <c2>
vera

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio

if(n >= 5 && n<10)

5 <= n < 10

printf(n nellintervallo );
printf([5, 10)\n);
}

printf()
printf()

n=20;

n = 20

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esercizio 1
Scrivere un programma che determini il massimo valore tra
quattro numeri acquisiti da tastiera.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esercizio 1
Scrivere un programma che determini il massimo valore tra
quattro numeri acquisiti da tastiera.
UNIDEA DIVERSA DA QUELLA GIA VISTA
1) Acquisisci i numeri (x, y, v, z)
2) Se (x>y && x>v && x>z)
il maggiore x
altrimenti //siamo sicuri che x non massimo
se (y>v && y>z)
il maggiore y
altrimenti //siamo sicuri che n x n y siano massimi
se (v>z)
il maggiore v
altrimenti il maggiore z
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

int x, y, v, z, max;
printf("Inserisci x\n");
scanf("%d%d%d%d",&x, &y, &v, &z);
if(x>y && x>v && x>z)
max=x;
else if(y>v && y>z)
max=y;
else if(v>z)
max=v;
else max=z;
printf("Massimo = %d\n", max);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esercizio 2
Scrivere un programma che continua ad acquisire un intero fino
a quando lutente non inserisce un numero strettamente positivo
e multiplo di 100, dopodich lo stampa a video.
Esempio:
Lutente inserisce
-100
34
49
200

Prof. M. Giacomin

A questo punto il calcolatore


stampa 200.

Elementi di Informatica e Programmazione Universit di Brescia

Lidea
Ovviamente, mi serve un ciclo che continui ad acquisire
numeri fino a quando il numero inserito non sia corretto
(strettamente positivo e multiplo di 100).
Dato che devo acquisire almeno un numero, posso pensare di
usare un ciclo do-while (a condizione finale)
do{
printf(Inserisci un numero str. positivo multiplo di 100\n);
scanf(%d, &n);
} while (!(n>0 && n%100==0));

lo stesso:
Prof. M. Giacomin

while (n<=0 || n%100 != 0);

Elementi di Informatica e Programmazione Universit di Brescia

Esercizio 3
Scrivere un programma che determini se un anno acquisito
da tastiera bisestile. Un anno bisestile se il suo numero
divisibile per 4, con l'eccezione che gli anni secolari
(quelli divisibili per 100) sono bisestili solo se divisibili per 400

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

Esercizio 3
Scrivere un programma che determini se un anno acquisito
da tastiera bisestile. Un anno bisestile se il suo numero
divisibile per 4, con l'eccezione che gli anni secolari
(quelli divisibili per 100) sono bisestili solo se divisibili per 400
int anno;
printf("Inserisci lanno\n");
scanf(%d, &anno);
if( ((anno % 100 !=0) && (anno % 4 ==0)) || anno%400==0)
printf(Anno bisestile\n");
else printf(Anno non bisestile\n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

RISOLVERE
I TEMI DESAME

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Pietro Piller Cottrer


Marianna Longa

Arianna Follis

SPIEGAZIONE LUCIDO PRECEDENTE


Purtroppo o per fortuna, non esistono regolette da applicare
Come in molti sport:
- bisogna imparare una tecnica che ha una sua teoria ma
- bisogna fare esercizio ma
- bisogna abituarsi ad applicare gli accorgimenti tecnici
gi quando si affrontano esercizi semplici:
solo cos la tecnica verr poi applicata spontaneamente
negli esercizi pi complicati
Studiare solo sulla carta non porta lontano
Anche bruciare le tappe non porta lontano:
bisogna sforzarsi di applicare la tecnica fin da subito
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

SVILUPPO DI UN PROGRAMMA C
Capire il problema
(eventualmente: provare a risolvere qualche istanza!)
Pensare a come risolverlo (come faremmo noi?)
Arrivare ad un algoritmo per passi successivi,
partendo da una descrizione pi astratta e poi
scomponendola in passi sempre pi elementari
[NB: possibile tornare indietro e modificare
lo schema di partenza]
fino ad arrivare al linguaggio C

ERRORE TIPICO: buttarsi a scrivere il codice di getto

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

PASSI 1 e 2
molto utile risolvere delle istanze a mano
- favorisce la comprensione corretta del problema
- tipicamente suggerisce unidea informale di un algoritmo
NB: se non sapete risolvere voi il problema, improbabile che
ci riesca il vostro programma!
quasi sempre inutile ripescare formule o metodi astrusi
dalla vostra memoria

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

PASSI 3 e 4 (metodo dei raffinamenti successivi


Scomporre il problema in sottoproblemi da affrontare dopo
- usare dove serve lo pseudocodice
- nel farlo, affrontare subito il caso generale:
i casi specifici verranno affrontati in un momento successivo!
[ERRORE TIPICO: programma che inizia con una sequela di if]
- eventualmente tornare indietro se viene in mente una soluzione
pi semplice/elegante o pi ordinata
Per ogni sottoproblema individuato, continuare la scomposizione
indipendentemente luno dallaltro
Il processo termina quando tutto espresso in linguaggio C
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

LE COSE PIU DIFFICILI DA IMPARARE (1)


Applicare il metodo dei raffinamenti successivi al giusto livello di
astrazione : lastrazione deve semplificare il processo risolutivo
permettendo di concentrarci sul nocciolo del problema.
ESEMPIO
Acquisisci dati
Si adatta praticamente a tutti gli
Elabora dati
esercizi, ma non serve a molto
Stampa risultati
Imparare a tornare indietro fin dalle prime fasi del processo di
scomposizione per raffinamenti successivi:
- soluzioni pi eleganti semplificano le fasi successive
e minimizzano gli errori nella stesura del codice!
- pi semplice e veloce tornare indietro allinizio
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

LE COSE PIU DIFFICILI DA IMPARARE (2)


nella stesura di un ciclo, occorre:
- identificare le variabili chiave necessarie
- attribuire il significato preciso che devono assumere allinizio
di ogni iterazione; specificare la condizione di permanenza
di conseguenza!

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

AVVISI
Vedremo una serie di esercizi tratti dai temi desame:
in un singolo esercizio, i diversi passi possono avere un
ruolo pi o meno accentuato [per alcuni pi complesso il processo
di raffinamento successivo, per altri si arriva direttamente al codice
ma la chiave dare un significato preciso alle variabili, ecc. ecc.]
In aula, vedremo pochi esercizi significativi: tanti esercizi sarebbero
controproducenti, perch quello che importante
- esaminare approfonditamente pochi esercizi significativi, per
imparare in teoria la tecnica
- provare a rifarli da soli (NB: non esiste una sola soluzione!) per
imparare in pratica la tecnica
- provare poi da soli (con l aiuto del compilatore) a farne altri, per
far diventare la tecnica spontanea

QUINDI:
Faremo in aula esercizi tratti dai temi d esame e verranno
poi proposti esercizi desame individuali senza soluzione perch:
- possibile risolverli studiando bene gli esempi gi visti:
se non avete idea di come risolverli, significa che non avete
capito bene la tecnica in teoria e non bisogna guardare la
soluzione, ma riesaminare gli esempi fatti in aula e rifletterci su
- per imparare la tecnica in pratica dovete arrivare in fondo
da soli, senza guardare la soluzione (altrimenti non imparate)
- assolutamente indispensabile commettere errori ma abituarsi
a scoprirli e correggerli da soli (usando il compilatore!)
per poi non commetterli pi: guardando la soluzione uno
non sbaglia e se non si sbaglia non si impara
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

ESERCIZIO 1
Scrivere un programma che calcoli il fattoriale di un numero intero
maggiore o uguale a 0 fornito dallutente.

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

Primo passo: capire il testo e soprattutto il problema (se non si sa


da che parte prendere , provare a risolvere qualche
istanza a mano)
5! = 5*4*3*2
3! = 3*2
1! = 1

In generale, N! pari a:
1
se N = 0 o N = 1
2**N
se N > 1

0! = 1

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

Secondo passo: individuare un metodo risolutivo


CONSIGLIO: pensare prima al caso generale,
poi considerare i casi particolari!
N! = 2*3*4*5**N
Variabile fatt
per mantenere il
risultato corrente
Variabile i che varia da 2 a N

Usare una variabile fatt, posta inizialmente a 1.


Successivamente moltiplicarla per 2, ,N:
fatt=1
fatt=fatt*2

fatt=fatt*N
Docente: M. Giacomin

Si user un ciclo per ripetere


la moltiplicazione per i=2, N

Elementi di Informatica e Programmazione Universit di Brescia

13

Terzo passo: sviluppare lalgoritmo


In questo caso, probabilmente uno arriva quasi al codice, anche
se una prima scomposizione potrebbe essere
ACQUISISCI NUMERO n
CALCOLA fattoriale(n)
STAMPA fattoriale calcolato
Come visto, abbiamo dei casi particolari (n=0 e n=1)
e il caso generale
CONSIGLIO: pensare prima al caso generale,
poi considerare i casi particolari!

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

printf( Inserire il numero N:\n );


scanf( %d ,&n);
fatt=1;
for(i=2; i<=n; i=i+1)

// i: numero per cui devo moltiplicare

fatt=fatt*i;
printf( Fattoriale di %d = %d\n ,n,fatt);

NB: ci si accorge che i casi particolari sono gi risolti!!!


per n = 0 o 1, fatt risulta correttamente 1
(il ciclo for non viene mai eseguito)

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

Ovviamente, il programma completo sar il seguente


#include<stdio.h>
#include<stdlib.h>
int main(int argc, char*argv[]){
int n, fatt, i;
printf( Inserire il numero N:\n );
scanf( %d ,&n);
fatt=1;
for(i=2; i<=n; i=i+1)
fatt=fatt*i;
printf( Fattoriale di %d = %d\n ,n,fatt);
system( pause );
return 0;
}
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

ESERCIZIO 2
Scrivere un programma che, ricevuto in ingresso un intero strettamente
maggiore di 0, determini se tale numero primo.

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

ESERCIZIO 2
Scrivere un programma che, ricevuto in ingresso un intero strettamente
maggiore di 0, determini se tale numero primo.
Primo passo: provare a risolvere a mano qualche istanza del problema
Es. 8 non primo ( divisibile per 2 e per 4)
7 primo ( divisibile solo per 1 e per 7, non per 2, 3, 4, 6)
Secondo passo: individuare un metodo risolutivo
Dato N, verifico se divisibile per 2, 3, n-1
se non divisibile per nessuno: il numero primo
se esiste un divisore: il numero non primo
E facile rendersi conto che basta un ciclo con un indice i che
va da 2 a n/2 (divisione intera)
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Terzo e quarto passo: sviluppare un algoritmo


int n, i, primo;
printf( Inserisci un numero positivo\n );
scanf("%d",&n);
primo=1;

//indica se tutti i numeri interni non dividono n

for(i=2; i<=n/2; i=i+1)

//prova con tutti i numeri da 2 a n/2

if(n%i == 0)
primo=0;
if(primo==1)
printf( Il numero primo\n );
else printf( Il numero non primo\n );

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

19

ESERCIZIO 3
Scrivere un programma che acquisisce da tastiera un numero intero n
maggiore o uguale a 0 (ripetendo lacquisizione in caso di numero
negativo) ed un intero x, quindi calcola e stampa la sommatoria
n

i
x

i =0

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

Primo passo: Risolvere qualche istanza


Es. con n=4 e x=2
= 20 + 21 + 22 + 23 + 24
= 1 + 2 + 4 + 8 + 16
Es. con n=0 e x=2
= 20
=1
Secondo passo: metodo risolutivo
sommatoria=0;
ciclo con i che varia da 0 a n
sommatoria = sommatoria+xi
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

Terzo e quarto passo: Sviluppare un algoritmo


A)
ACQUISIZIONE DI n;
sommatoria=0;
for(i=0;i<=n; i=i+1)
sommatoria = sommatoria+xi;
STAMPA sommatoria

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

B)
int n, sommatoria, i, potenza;
do
scanf(%d, &n);
while(n<0);
sommatoria=0;
for(i=0;i<=n; i=i+1){
CALCOLA: potenzaxi

x*x*x
i volte

sommatoria = sommatoria+potenza;
}
printf(La sommatoria risulta %d, sommatoria);

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

C)
int n, sommatoria, i, j, potenza;
do
scanf(%d, &n);
while(n<0);
sommatoria=0;
for(i=0;i<=n; i=i+1){
potenza=1;
for(j=1; j<=i; j=j+1)
potenza=potenza*x;
sommatoria = sommatoria+potenza;
}
printf(La sommatoria risulta %d, sommatoria);

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

Terzo e quarto passo alternativo: Sviluppare un algoritmo


B)
int n, sommatoria, i, potenza;
do
scanf(%d, &n);
while(n<0);

Ad ogni iterazione:
potenza=potenza*x;

sommatoria=0;
for(i=0;i<=n; i=i+1){
sommatoria = sommatoria+xi;
}
printf(La sommatoria risulta %d, sommatoria);

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

C)
int n, sommatoria, i, j, potenza;
do
scanf(%d, &n);
while(n<0);
sommatoria=0;
potenza=1;

// allinizio di ogni iterazione contiene xi

for(i=0;i<=n; i=i+1){
sommatoria = sommatoria+potenza;
potenza=potenza*x;
}
printf(La sommatoria risulta %d, sommatoria);

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

26

ESERCIZIO 4: dal tema desame ING-INF del 13 gennaio 2009


Si sviluppi un programma in linguaggio C che, ricevendo in ingresso
una sequenza di lunghezza arbitraria di almeno due numeri interi
diversi da zero, terminata da uno zero, produca in uscita i due
valori minimi letti in ingresso (escluso lultimo zero).
Ad esempio, ricevendo in ingresso la sequenza
7 2 19 4 45 3 7 9 3 0
produce in uscita

2 3

Altro esempio: ricevendo in ingresso la sequenza


7 2 19 4 2 3 7 9 3 0
produce in uscita 2 2
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

[10]
27

Primo passo: provare a risolvere a mano qualche istanza del problema


7 2 19 4 45 3 7 9 3 0
- Allinizio (7, 2) sono i valori minimi
- Considero 19:
i minimi rimangono (7, 2)
- Considero 4:
i minimi diventano (4, 2)
- Considero 45:
i minimi rimangono (4, 2)
- Considero 3:
i minimi diventano (3, 2)

Gi si intravede un metodo risolutivo (passo2):


usare un ciclo per acquisire i numeri (termina con 0)
mantenere due variabili min1 e min2 con i minimi
ad ogni iterazione, acquisire un nuovo numero e
aggiornare di conseguenza min1 e min2
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

28

Nota: come faccio ad aggiornare min1 e min2?


min1

min2

num
E pi facile se mantengo min1 e min2 ordinati
(min1<=min2)

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

29

Terzo passo: sviluppare lalgoritmo


Acquisisci i primi due numeri e inizializza min1, min2
con i due numeri stessi in modo che valga min1<=min2
scanf( %d , &n);
while(n!=0){

//min1 e min2: minimi correnti ordinati

aggiorna min1 e min2 tenendo conto di n;


scanf( %d%, &n);
}

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

30

Terzo passo: sviluppare lalgoritmo


int num, min1, min2;
printf( Inserisci la sequenza di numeri\n );
scanf( %d , &num);
min1=num;
scanf( %d , &num);
if(min1<=num)
min2=num;
else{
min2=min1;
min1=num;
}

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

31


scanf( %d , &num);
while(num!=0){
if(num<min1){
min2=min1;
min1=num;
}
else if(num<min2)
min2=num;
scanf( %d , &num);
}
printf( I numeri minimi sono %d e %d\n , min1, min2);

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

32

ESERCIZIO 5
Scrivere un programma che, ricevuto in ingresso un intero N0,
calcoli lN-simo elemento della sequenza F dei numeri di Fibonacci,
definita cos:
F(0) = 0
F(1) = 1
F(K) = F(K-1)+F(K-2)

per K2

In altre parole, la sequenza dei numeri di Fibonacci la seguente:


0, 1, 1, 2, 3, 5, 8, 13,
in cui ciascun numero, dal terzo in poi, la somma dei due che lo
precedono.

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

33

Primo passo: provare a risolvere a mano qualche istanza del problema


N=2: 0, 1, 1

il programma restituisce 1

N=3: 0, 1, 1, 2

il programma restituisce 2

Secondo passo: individuare un metodo risolutivo


N=0, N=1: casi base (il programma deve restituire 0 o 1)
N2: uso un contatore I che arriva fino a N:
ad ogni passo devo calcolare il nuovo numero di Fibonacci F(I):
devo sommare gli ultimi due numeri di Fibonacci ottenuti
quindi, memorizzo in due variabili Fpenultimo e Fultimo gli
ultimi due numeri di Fibonacci ottenuti e, ad ogni passo:
- Fpenultimo deve diventare Fultimo
- Fultimo deve diventare Fpenultimo+Fultimo
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

34

Terzo passo: sviluppare l algoritmo


NB: per cominciare trascuriamo i casi base (quelli sono semplici e ci
pensiamo dopo): risolviamo il cuore del problema
Errore comune: cominciare a scrivere il codice senza avere
in testa l algoritmo o, cosa ancora peggiore,
un idea del metodo risolutivo
TIPICAMENTE, QUESTO PORTA A SCRIVERE
UN PO DI IF PER GESTIRE I PRIMI CASI
SPECIFICI (se N==0, se N==1, se N==2, )
TIPICAMENTE, QUESTO INDUCE A RITENERE
CHE SI E COMINCIATO A SCRIVERE IL CODICE
SENZA PRIMA PENSARE ALLALGORITMO

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

35

Terzo passo: sviluppare l algoritmo


NB: per cominciare trascuriamo i casi base (quelli sono semplici e ci
pensiamo dopo): risolviamo il cuore del problema
Fpenultimo = 0;
Fultimo = 1;

// comincio con i primi due numeri della serie

i = 1;

// i riferito allultimo numero di Fibonacci Fultimo

while(i<N){

Docente: M. Giacomin

// esco quando i==N, quando Fultimo contiene F(i)=F(N)

Elementi di Informatica e Programmazione Universit di Brescia

36

Terzo passo: sviluppare l algoritmo


NB: per cominciare trascuriamo i casi base (quelli sono semplici e ci
pensiamo dopo): risolviamo il cuore del problema
Fpenultimo = 0;
Fultimo = 1;

// comincio con i primi due numeri della serie

i = 1;

// i riferito allultimo numero di Fibonacci Fultimo

while(i<N){

// esco quando i==N, quando Fultimo contiene F(i)=F(N)

Aggiorna Fultimo
Aggiorna Fpenultimo
i=i+1;
}

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

37

Terzo passo: sviluppare l algoritmo


NB: per cominciare trascuriamo i casi base (quelli sono semplici e ci
pensiamo dopo): risolviamo il cuore del problema
Fpenultimo = 0;
Fultimo = 1;

// comincio con i primi due numeri della serie

i = 1;

// i riferito allultimo numero di Fibonacci Fultimo

while(i<N){

// esco quando i==N, quando Fultimo contiene F(i)=F(N)

Aggiorna Fultimo
Aggiorna Fpenultimo

Fultimo = Fpenultimo + Fultimo;


Fpenultimo = ? Fultimo ?

i=i+1;
}

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

38

Terzo passo: sviluppare l algoritmo


NB: per cominciare trascuriamo i casi base (quelli sono semplici e ci
pensiamo dopo): risolviamo il cuore del problema
Fpenultimo = 0;
Fultimo = 1;

// comincio con i primi due numeri della serie

i = 1;

// i riferito allultimo numero di Fibonacci Fultimo

while(i<N){

// esco quando i==N, quando Fultimo contiene F(i)=F(N)

NEWFIB= Fpenultimo+Fultimo;

// nuovo ultimo numero di Fibonacci

Fpenultimo=Fultimo;

// aggiorno Fpenultimo

Fultimo=NEWFIB;

// aggiorno Fultimo

i=i+1;

// aggiorno i, che si riferisce di nuovo a Fultimo

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

39

Terzo passo: sviluppare l algoritmo


NB: per cominciare trascuriamo i casi base (quelli sono semplici e ci
pensiamo dopo): risolviamo il cuore del problema
Fpenultimo = 0;
Fultimo = 1;

// comincio con i primi due numeri della serie

i = 1;

// i riferito allultimo numero di Fibonacci Fultimo

while(i<N){

// esco quando i==N, quando Fultimo contiene F(i)=F(N)

NEWFIB= Fpenultimo+Fultimo;

// nuovo ultimo numero di Fibonacci

Fpenultimo=Fultimo;

// aggiorno Fpenultimo

Fultimo=NEWFIB;

// aggiorno Fultimo

i=i+1;

// aggiorno i, che si riferisce di nuovo a Fultimo

Ora posso considerare i casi base:


- il caso N=0 non gestito (il programma porta Fultimo a 1)
- il caso N=1 gestito (il ciclo while non viene eseguito!)
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

40

int n, i, fultimo, fpenultimo, newfib;


printf("Inserire il numero N:\n");
do
scanf("%d",&n);
while(n<0);
fpenultimo=0;
fultimo=1;
i=1;
while(i<n){
newfib=fpenultimo+fultimo;
fpenultimo=fultimo;
fultimo=newfib;
i=i+1;
}
if(n==0)

//gestione del caso base

fultimo=0;
printf("Numero di Fibonacci %d = %d\n",n,fultimo);
Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

41

Linguaggio C
Tipi predefiniti

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Il concetto di tipo (reprise)


Nome che indica
Un insieme di valori
Un insieme di operatori applicabili su questi valori
Caratterizza in particolare
le costanti
- esistono costanti di diverso tipo
- Es: 1 una costante intera, 1.5 in virgola mobile
le variabili
- dichiarazione: <tipo> <identificatore>
NB: il tipo di una variabile quello dei suoi possibili valori
i risultati delle espressioni
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

TIPI E MASCHERAMENTO IMPLEMENTAZIONE


short int i1;

int i2;

float f;

LINGUAGGIO C
COMPILATORE

16 bit!

CA2
o CA1 o

32 bit!

CA2
o CA1 o

32 bit!

IMPLEMENTAZIONE

IEEE754
o IBM o DIGITAL o

Il C maschera i dettagli dellimplementazione


- non occorre conoscere se gli interi sono rappresentati in Ca2 o Ca1
ma fino a un certo punto!
- alcune caratteristiche sono dipendenti dallimplementazione
(es: valori max e min di una variabile intera)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Tipi di dati predefiniti vs definiti dallutente in C

Esistono due categorie di tipi di dati in C:


1. Predefiniti: disponibili direttamente nel linguaggio
- p.es. il tipo int predefinito
2. Definiti dallutente: necessario che il programmatore li
definisca con specifiche istruzioni C (vedremo in futuro)
- p.es. un tipo studente o squadra

In C i tipi predefiniti sono tutti numerici


- tipi interi (signed e unsigned)
- tipi in virgola mobile

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

I TIPI INTERI

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Un esempio: programma per calcolare 2n


int n, potenza, i;
printf(Inserisci il numero n\n);
scanf( %d ,&n);
potenza=1;
for(i=1; i<=n; i=i+1)
potenza=potenza*2;
printf( 2 elevato a %d = %d\n ,n,potenza);

Inserire il numero n!
30!
2 elevato alla 30 = 1073741824!
!
Inserire il numero n!
31!
2 elevato alla 31 = -2147483648!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

????
6

Esempio: programma potenza modificato


unsigned int n, potenza, i;
printf(Inserisci il numero n\n);
scanf( %u ,&n);
potenza=1;
for(i=1; i<=n; i=i+1)
potenza=potenza*2;
printf( 2 elevato a %u = %u\n ,n,potenza);

Inserire il numero n!
31!
2 elevato alla 31 = 2147483648!
!
Inserire il numero n!
32!
2 elevato alla 32 = 0! ????
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Tipi interi e modificatori di tipo


Diversi tipi/modificatori in funzione delle dimensioni
per rappresentare i valori (in ordine crescente):
char
short int
int
long int
!
Versioni signed (default se non indicato) vs unsigned
- signed: bit utilizzati per rappresentare positivi e negativi
- unsigned: bit utilizzati per rappresentare valori naturali
(aumenta il massimo rappresentabile!)!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Specchietto
[signed] char

[signed] short int

[signed] int

[signed] long int

unsigned char

unsigned short int

unsigned int

unsigned long int

Il C non specifica le dimensioni, ma fissa dei vincoli:


- sizeof(char) sizeof(short int) sizeof(int) sizeof(long int)
- sizeof(char) 1, sizeof(short int) 2,
sizeof(int) 2, sizeof(long int) 4

Dimensioni esatte dipendono dallimplementazione


Dimensione del tipo char corrisponde alla codifica dei caratteri
usata nella macchina (es: ASCII 1 byte).

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Tipi tipici in una macchina a 32 bit con codifica ASCII


char
8 bit

Valori interi compresi tra:


-128 e +127 (signed)
0 e +255 (unsigned)

short int
16 bit

Valori interi compresi tra:


-32,768 e +32,767 (signed)
0 e +65,535 (unsigned)

int e long int


32 bit

Prof. M. Giacomin

Valori interi compresi tra:


-2,147,483,648 e +2,147,483,647 (signed)
0 e +4,294,967,295 (unsigned)
Elementi di Informatica e Programmazione Universit di Brescia

10

Tipi tipici in una macchina a 64 bit


short int
16 bit

Valori interi compresi tra:


-32,768 e +32,767 (signed)
0 e +65,535 (unsigned)

32 bit

Valori interi compresi tra:


-2,147,483,648 e +2,147,483,647 (signed)
0 e 4,294,967,295 (unsigned)

int

long int
64 bit

Prof. M. Giacomin

Valori interi compresi tra:


-9,223,372,036,854,775,808 e + (signed)
0 e +18,446,744,073,709,551,615 (unsigned)
Elementi di Informatica e Programmazione Universit di Brescia

11

Esempio 1 (presupponendo dimensione char=8 bit)


char a;
a=300;

in questo caso 300 non rientra nellintervallo


dei valori rappresentabili in un char

Esempio 2
int a;
a=300;

Prof. M. Giacomin

in questo caso 300 rientra nellintervallo


dei valori rappresentabili in un int,
quindi tutto viene gestito correttamente

Elementi di Informatica e Programmazione Universit di Brescia

12

Costanti intere (senza virgola)


Esempio:
int a = 5;

b = c+13;

di che tipo sono?

Per default sono di tipo int


Se il valore non rappresentabile con un int:
long int e se non sufficiente unsigned long int
Se si aggiunge L/U si intendono di tipo long/unsigned
Esempi:
unsigned long int a = 5UL;
long int b = -10L;
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

Costanti carattere
Un carattere tra singoli apici indica il corrispondente valore
numerico secondo il codice adottato (es. ASCII). A rigore il tipo
delle costanti carattere int, non char
Caratteri di escape: rappresentano caratteri particolari, es:
new-line
\b backspace
\ apice singolo
\n

Esempio
char carattere, a=5;
carattere=a;
// carattere=97 (codice ASCII del carattere a)
carattere=a;
// carattere=5
carattere=\n;
// OK
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

Stampare valori (la printf rivisitata)


printf(stringa di formato, lista di espressioni);
Stringa di formato
Tra doppi apici: caratteri normali e specifiche di conversione
I caratteri normali vengono stampati normalmente
Specifiche di conversione
Iniziano con il simbolo %
Rappresentano un segnaposto per il valore corrispondente
nella lista successiva
Stabiliscono come il valore debba essere convertito
dalla forma binaria interna ai caratteri da stampare
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

Tabella specifiche di conversione pi comuni


Spec. convers. Tipo

Formato di stampa

%d (%i)

char, short int, int

Notazione decimale

%c

char, short int, int

Carattere corrispondente (es.


ASCII)

%u

unsigned char, unsigned short int,


unsigned int

Notazione decimale

%o

unsigned char, unsigned short int,


unsigned int

Notazione ottale

%x, %X

unsigned char, unsigned short int,


unsigned int

Notazione esadecimale
(x: lettere minuscole, X: maiuscole)

%ld (%li)

long int

Notazione decimale

%lu

unsigned long int

Notazione decimale

%lo

unsigned long int

Notazione ottale

%lx, %lX

unsigned long int

Notazione esadecimale
(x: lettere minuscole, X: maiuscole)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

Acquisire valori (la scanf rivisitata)


scanf(stringa di formato, lista di variabili);
Stringa di formato
Tra doppi apici: caratteri normali e specifiche di conversione
I caratteri normali usati per pattern matching, non stampati!!!
Specifiche di conversione
Iniziano con il simbolo %
Rappresentano un segnaposto per la variabile corrispondente
nella lista successiva
Stabiliscono come i caratteri inseriti debbano essere interpretati
e convertiti nella forma binaria interna
In molti casi stesso significato rispetto alla printf (non sempre!)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

Tabella specifiche di conversione pi comuni


Spec. convers. Tipo

Input

%d

int

Numero in notazione decimale

%c

char

Un carattere (es. ASCII), convertito


in numero

%u

unsigned int

Intero senza segno, notaz. decimale

%hd

short int

Numero in notazione decimale

%hu

unsigned short int

Intero senza segno, notaz. decimale

%ld

long int

Numero in notazione decimale

%lu

unsigned long int

Intero senza segno, notaz. decimale

Esempio
short unsigned int unsint;
scanf(%hu, &unsint);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Esempio 2
char carattere;
scanf(%c, &carattere);
printf(Il carattere %c, ma anche %d\n, carattere, carattere);
scanf(%d, &carattere);

//funziona lo stesso, credeteci

printf(Il carattere %c, ma anche %d\n, carattere, carattere);

ESEMPIO DI
ESECUZIONE

ESEMPIO DI
ESECUZIONE

Prof. M. Giacomin

a
Il carattere a, ma anche 97
97
Il carattere a, ma anche 97
1
Il carattere 1, ma anche 49

Elementi di Informatica e Programmazione Universit di Brescia

19

Esercizio individuale
Acquisire da tastiera un carattere. Determinare se si tratta di
una vocale o di una consonante.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

Soluzione
Acquisire da tastiera un carattere. Determinare se si tratta di
una vocale o di una consonante.
char n;
printf(Inserisci un carattere\n);
scanf(%c, &n);
if(n==a || n==e || n==i || n==o || n==u)
printf(Il carattere una vocale\n);
else printf(Il carattere una consonante\n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

I TIPI IN VIRGOLA MOBILE


(FLOATING POINT)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

Tipi in virgola mobile (floating point)


float

double

long double

Il C non specifica le dimensioni e neppure il formato di


rappresentazione (di solito IEEE): dipendono dallimplementazione
La precisione crescente da float a long double
Non ci sono le varianti signed vs unsigned (cf. codifica v. mobile)
Tipicamente:
float

double
32 bit

Prof. M. Giacomin

64 bit

Elementi di Informatica e Programmazione Universit di Brescia

23

Costanti floating point


Costanti che contengono:
- il punto decimale, ad esempio 5.0
- e/o lesponente (preceduto da e o E), ad esempio
43E0 4.3E1 4.3e1 (indicano tutte il valore 43)
Per default sono di tipo double
Se si aggiunge f o F: tipo float l o L:long double
Esempio:
double a = 5.2;

// per default 5.2 di tipo double

float b=6.3f;
long double c=10.0L;

Prof. M. Giacomin

// NB: 10L sarebbe long int

Elementi di Informatica e Programmazione Universit di Brescia

24

Stampare valori floating point con printf


Tabella specifiche di conversione pi comuni
Spec. convers. Tipo

Formato di stampa

%f

float, double

Notazione decimale

%e, %E

float, double

Notazione scientifica (esponente preceduto da e o E)

%g, %G

float, double

Formato f oppure e (f o E), a seconda del valore


dellesponente. Zeri inutili non visualizzati.

%Lf

long double

Notazione decimale

%Le, %LE

long double

Notazione scientifica (esponente preceduto da e o E)

%Lg, %LG

long double

Formato f oppure e (f o E), a seconda del valore


dellesponente. Zeri inutili non visualizzati.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

Esempio
float gradi=36.6f;
printf( La tua temperatura di %f gradi , gradi);

Stampa La tua temperatura di 36.600000 gradi


printf( La tua temperatura di %g gradi , gradi);

Stampa La tua temperatura di 36.6 gradi

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

26

Acquisire valori floating point con scanf


Specifiche di conversione pi comuni
%f
%lf
%Lf

per variabili di tipo float


per variabili di tipo double
per variabili di tipo long double

Esempio
float fl;
double dbl;
long double longdbl;
scanf(%f, &fl);
scanf(%lf, &dbl);
scanf(%Lf, &longdbl);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

27

Approssimazioni nel calcolo in virgola mobile


ESEMPIO
float x=-1.5e38f;
float y=1.5e38f;
float r1, r2;
r1=(x+y)+1.0f;

// r1=1

r2=x+(y+1.0)f;

// r2=0

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

28

Linguaggio C
Operatori, Espressioni e
Conversioni di tipo
Universit degli Studi di Brescia
Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

NB: verranno riesaminate in forma pi sistematica e generale molte


nozioni gi viste, precisando concetti introdotti in modo informale

Expression statement
<espressione>;
Un particolare tipo di istruzione non composta
Effetto: viene calcolata lespressione (e il risultato si butta via)!!!
Definizione non esaustiva di <espressione>:
- una costante
- una variabile
- un operatore applicato ad espressioni

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempi di expression statement


5;

// corretto e leffetto nullo!

((a+2)*5)+4;

// IDEM

a==b;

// sembra assurdo, ma permesso!

Esempi che NON sono expression statement


for(i=1; i<=10; i=i+1) printf(*);

// non <espressione>;

{a==b;}

// non <espressione>;
// bens un blocco!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO SEMPLICE
int a=3, b=7, c=10;
a + b + c*2 + a*(b-a);

Il C tratta le espressioni come ci aspettiamo


Applica un operatore alla volta, sostituendolo
con il risultato restituito e prosegue
Ordine di applicazione determinato da:
- parentesi
- priorit tra operatori
- associativit degli operatori

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Concetto di operatori in C
Sono delle specie di funzioni:
- ricevono in ingresso uno o pi operandi dello stesso tipo
- restituiscono un risultato di un certo tipo (eventualmente diverso)
Esistono operatori binari (due operandi) ed operatori unari
5+2
-(-5)

// operatore aritmetico + su int


// operatore unario su int

Per ogni tipo operatori specifici: p.es. per int esiste %, per il float no
Diversi operatori possono avere nome uguale:
p.es. / diverso per int vs. float
* sia binario (moltiplicazione) sia unario (cf puntatori)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

DOMANDA LECITA
A COSA SERVONO GLI EXPRESSION STATEMENT?
- tipicamente negli expression statement il programmatore usa
operatori che, oltre a produrre un valore, hanno degli effetti
collaterali (es. cambiano il valore di una variabile, chiamano
una funzione)

NEL SEGUITO VENGONO ESAMINATI VARI OPERATORI,


PARTENDO DA UN OPERATORE BEN NOTO CON UN
EFFETTO COLLATERLAE BEN NOTO!!!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Operatore di assegnamento
Sintassi:
<identificatore> = <espressione>

in cui <identificatore>: lvalue, <espressione>: rvalue


Effetto collaterale:
- assegna a <identificatore> (lvalue) il risultato (rvalue)
dellespressione
Risultato restituito:
- valore (rvalue) effettivamente assegnato a <espressione>
NB: <identificatore> = <espressione> a sua volta unespressione!
Pu essere direttamente utilizzata come expression statement
oppure come sottoespressione di unespressione pi complessa!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO
int x = 3;
int y;

// non un assegnamento, ma uninizializzazione

y = (x+2)*3;

// expression statement (effetto: y=15)

y=(x=3);

// expression statement y=<espressione>;


// Effetto: x=3, y=3

y=y+(x=5);

// expression statement
// Effetto: x=5, y=8

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Operatori aritmetici
Permettono di effettuare le normali operazioni aritmetiche
Corrispondono a funzioni:
- ricevono in ingresso uno o pi valori (rvalue) dello stesso tipo
- restituiscono un valore (rvalue) dello stesso tipo rispetto a operandi
Sono leggermente diversi per tipi interi o virgola mobile

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Operatori aritmetici (A)


TIPI INTERI (char, int, short int, long int)
Operatori binari:
+ addizione
* moltiplicazione
- sottrazione
/ divisione intera
% resto
Operatore unario: segno negativo -

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

Esempio tipico di utilizzo delloperatore resto


int a;
printf()

printf(la variabile a contiene un numero );


if((a%2) ==0)

a%2==0

printf(pari)

printf(pari\n);

printf
(dispari)

else
printf(dispari\n);
printf(E comunque un numero!\n);
printf()

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

Operatori aritmetici (B)


TIPI VIRGOLA MOBILE (float, double, long double)
Operatori binari:
+ addizione
* moltiplicazione
- sottrazione
/ divisione
Operatore unario: segno negativo NB: Loperatore resto non esiste per i tipi in virgola mobile (infatti
non ha senso): utilizzarlo d un errore di compilazione
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

Un esempio: media tra tre numeri interi


int a, b, c, media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;
printf(La media tra %d e %d e %d fa %d\n, a,b,c,media);

Quale numero viene stampato?

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

Un esempio: media tra tre numeri interi


int a, b, c, media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;
printf(La media tra %d e %d e %d fa %d\n, a,b,c,media);

Quale numero viene stampato?

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

Un esempio: media tra tre numeri interi


float a, b, c, media;
a=5;
b=7;
c=11;
media=(a+b+c)/3.0f;
printf(La media tra %f e %f e %f fa %f\n, a,b,c,media);

Quale numero viene stampato?

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

Un esempio: media tra tre numeri interi


float a, b, c, media;
a=5;
b=7;
c=11;
media=(a+b+c)/3.0f;
printf(La media tra %f e %f e %f fa %f\n, a,b,c,media);

Quale numero viene stampato?

Prof. M. Giacomin

7.666667

Elementi di Informatica e Programmazione Universit di Brescia

16

OVERFLOW
Tra interi signed: comportamento non definito
Tra interi unsigned: risultato modulo 2n (n: numero di bit usati)
Tra valori in virgola mobile: comportamento non definito
Esempi (ipotizzando limiti tipici su macchina a 32 bit)
// max per unsigned long int: 4294967295
unsigned long int ul1=4294967290, ul2=10, ul3;
ul3= ul1+ul2; // ul3=4
// max per signed long int: 2147483647
long int l1=2147483647, l2=1, l3;
l3= l1+l2;

Prof. M. Giacomin

// comportam. indefinito (probabilmente -2147483648)

Elementi di Informatica e Programmazione Universit di Brescia

17

Operatori di incremento e decremento


Operatori unari: operando lvalue, restituiscono un rvalue
Effetto collaterale: incremento/decremento delloperando
Esempi esplicativi
++a; //a=a+1 (come tale la valutazione dellespressione ++a a+1,
ovvero prima viene incrementata la variabile a
poi viene valutata lespressione)
a++; //a=a+1, in cui per la valutazione dellespressione a++ a
(prima si valuta lespressione poi si incrementa a)
--a; //a=a-1, in cui la valutazione dellespressione a-1
a--;

//a=a-1, in cui la valutazione dellespressione a

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Esempi su forma prefissa e postfissa


int x,y;
x=5;
y=x++;
x=5;
y=(x=x+1);
x=5;
y=++x;

Prof. M. Giacomin

// y=5, x=6
// equivale a y=x; x=x+1
// x=6, y=6

//x=6, y=6
//equivale a x=x+1;y=x

Elementi di Informatica e Programmazione Universit di Brescia

19

Assegnamenti composti
<e1> <op>= <e2> equivalente a <e1> = <e1> <op> (<e2>)
<e1> lvalue, <e2> rvalue
Disponibile con operatori aritmetici pi comuni, p.es.

Prof. M. Giacomin

a+=b;

// a=a+b

a-=b;

// a=a-b

a*=b;

// a=a*b

a/=b;

// a=a/b

a%=b;

// a=%b

(solo con interi)

Elementi di Informatica e Programmazione Universit di Brescia

20

Operatori relazionali e logici (tecnicamente)


Il C non fornisce i tipi booleani, solo numerici
si usano valori interi:
- 0 indica falso
- 0 indica vero
GLI OPERATORI RELAZIONALI E LOGICI
HANNO COME OPERANDI VALORI (rvalue) INTERI
E PRODUCONO UN (rvalue) INTERO

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

Operatori relazionali tecnicamente


Confrontano due valori e restituiscono un valore intero:
0 se la condizione non verificata (falso)
1 se la condizione verificata (vero)
Operatori disponibili
==
<
<=
>
>=
!=
Prof. M. Giacomin

uguale (da non confondere con = !!!!!!!!!)


minore
minore o uguale
maggiore
maggiore o uguale
non uguale
Elementi di Informatica e Programmazione Universit di Brescia

22

Operatori logici tecnicamente


Operatori logici:
!
NOT (operatore unario)
&&
AND (operatore binario)
||
OR (operatore binario)
Ricevono in ingresso dei valori numerici, interpretandoli come:
falso se 0
vero se diverso da 0
Restituiscono il corrispondente valore di verit (cfr. Algebra Boole)
rappresentato da un numero: 0 per falso, 1 per vero
Ad esempio, OR restituisce un valore 1 se almeno uno degli
operandi 0, restituisce 0 se entrambi gli operandi sono nulli
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

Esempio tecnico
int x=5, y, z;
y = (x==5);

\\ y=1

z = (x=5);

\\ z=5

z = (x>5);

\\ z=0

x = (x=x);

\\ x inalterato

x = (x==x);

\\ x=1

x = (x!=x);

\\ x=0

z = ((x<y) && (y!=1));

\\ z=0

z = ((x<y) || (y!=1));

\\ z=1

z = !(x<y);

\\ z=0

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

IF, IF-ELSE, WHILE, DO-WHILE, FOR: DEFINIZIONI VERE


Tecnicamente, le istruzioni if, while, do-while, ecc. valutano
unespressione numerica controllando se =0 o 0
IF

if (<espressione>)
<istruzione>;

<espressione>

0
<istruzione>

Esempio

if(1)
printf(*); //eseguito sempre!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

WHILE

while (<espressione>)
<istruzione>

<espressione>

0
<istruzione>

Esempio

while(1)
printf(*); //ciclo infinito!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

26

FOR
for(<exp1>;<exp2>;<exp3>)
<istruz>

<exp1>;

<exp2>
NB: <exp1>, <exp2>, <exp3>
sono semplicemente espressioni
che tipicamente corrispondono a
un assegnamento, una condizione,
un incremento, rispettivamente!

0
<istruz>
<exp3>;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

27

ESEMPI
for(a==b; 5; a++);

// sintatticamente corretto
// a==b non ha effetto
// genera un ciclo infinito!

for({a=1}; a<=10; a++)

// sintatticamente scorretto!

printf(*);
for(for(i=1; i<=5; i++) printf(*); a<10; a++)

//sintatt. scorretto!

printf(*);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

28

Operatore virgola
Sintassi:
<espressione1> , <espressione2>
Significato:
- prima viene valutata <espressione1>
- poi viene valutata <espressione2>
- il valore restituito quello di <espressione2>
Uso tipico: pi espressioni di inizializzazione in un ciclo for
Esempio: calcolare 1+2++10
for(somma=0, i=1; i<=10; i=i+1)
somma=somma+i;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

29

Precedenza e associativit degli operatori


Ogni operatore caratterizzato da:
- livello di precedenza:
pi operatori vengono applicati in ordine di precedenza
- associativit (sinistra o destra):
pi operatori dello stesso livello di precedenza raggruppano
gli operandi da sinistra o da destra
Le tabelle degli operatori riportano precedenza e associativit:
corrispondono quasi sempre al modo usuale o comune di applicare
gli operatori
Se si programma, nel dubbio usare parentesi!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

30

Operatori
prefissi

Associativita

++ -- () [] -> . indirez.
postfissi unari
++ -- + - ! ~ & * sizeof
() cast
* / %
binari
+ << >>
< <= > >=
== !=
&
^
|
&&
||
?:
= += -= *= /= %= &= ^= |= <<= >>=
,
Prof. M. Giacomin

da sinistra a destra
da destra a sinistra
da destra a sinistra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da destra a sinistra
da destra a sinistra
da sinistra a destra

Elementi di Informatica e Programmazione Universit di Brescia

31

Esempi
int x=5, y=6, z=3;
x= 6+x*y+z;

// x=6+(x*y)+z

y*=x+1;

// y=240, diverso da y=y*x+1

x=y=z;

ovvero 39

// associativo da destra a sinistra: a tutte


// viene assegnato il valore 3

if(x>y && x>v && x>z)

// equivale a if((x>y) && (x>v) && (x>z))

printf();

Esempio irreale con un C pazzo in cui = ha priorit su +


int x=5, y=10;
x= 6+y;

// x=6 e restituisce 6,
// 6+10 valore dellespressione non usato!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

32

CORTO-CIRCUITAZIONE DEL CALCOLO DI && e ||


Prima viene calcolato il valore delloperando sinistro
Se questo permette di determinare il valore dellespressione,
loperando destro non viene considerato
Esempio 1
if((i!=0) && (j/i >=10))
printf (Divisione maggiore o uguale a 10\n);

Esempio 2
if((i==0) || (j/i >100))
printf (Divisione per 0 o maggiore di 100\n);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

33

Conversioni di tipo
Due modalit per convertire un valore di un tipo in un altro tipo
- conversioni implicite:
operate dal compilatore (principalmente) quando un
operatore applicato ad operandi di tipo diverso:
conversione per assicurare che loperatore sia applicato ad
operandi dello stesso tipo!
- conversioni esplicite:
forzate dal programmatore con istruzioni opportune

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

34

Conversioni implicite (cenni)


Esempio 1
float a;
int b=5;
char c=6;
a=b+c;

//c convertito a int, (a+b) a float senza perdita precisione

Esempio 2
int a;
float b=2.5f;
double c=3;
a=b+c;

Prof. M. Giacomin

//b convertito a double, (b+c) ad int troncandolo a 5

Elementi di Informatica e Programmazione Universit di Brescia

35

Operandi di operatori aritmetici o relazionali


Tipo pi piccolo convertito nel tipo pi grande
Esempi:
char

int

x+y
float

a*b

double

x viene convertito a int


Loperatore + su int
e restituisce int
a viene convertito a double
Loperatore * su double
e restituisce double

NB: questa una versione semplificata, le regole del C sono


pi complesse (cfr. Appendice Tecnico per uno specchietto)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

36

Conversioni negli assegnamenti


La conversione verso il tipo della variabile assegnata:
- eventuale perdita di precisione
- risultato errato (senza senso) se rimpicciolente
Esempi: se f float, i int, c char
f = i;

// valore di i convertito in un float e assegnato a f


// (non c perdita di precisione o comunque limitata)
// es: se i=5, a f viene assegnato 5.0

i = f;

// valore di f convertito in int


// (perdita di precisione se f non un intero)
// es: se f=5.4, a i viene assegnato 5

c = 20000;
Prof. M. Giacomin

// assegnazione rimpicciolente (risultato errato)


Elementi di Informatica e Programmazione Universit di Brescia

37

ESEMPIO BANALE
long int i;
float f;
i=5L;
i=5;

//nessuna conversione
//conversione da int a long int

f=5;
f=5.0;
f=5.0f;

//conversione da int a float


//conversione da double a float
//nessuna conversione

/* le assegnazioni (ad i e f) sono di fatto equivalenti */


/* in pratica, negli assegnamenti le costanti possono essere
usate normalmente, senza preoccuparsi di caratterizzarne
esplicitamente il tipo */

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

38

ESEMPIO CON VARIANTI


Un esempio (poco ragionevole): media tra tre numeri interi
float a, b, c;
int media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;
printf(La media tra %f e %f e %f fa %d\n, a,b,c,media);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

39

Un esempio (poco ragionevole): media tra tre numeri interi


float a, b, c;
int media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;

//valore 7.666667 troncato e assegnato


//a media!
printf(La media tra %f e %f e %f fa %d\n, a,b,c,media);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

40

Un esempio: media tra tre numeri interi


int a, b, c;
float media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;
printf(La media tra %d e %d e %d fa %f\n, a,b,c,media);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

41

Un esempio: media tra tre numeri interi


int a, b, c;
float media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;
//valore intero 7 assegnato a media!
printf(La media tra %d e %d e %d fa %f\n, a,b,c,media);

7.000000

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

42

Un esempio: media tra tre numeri interi


int a, b;
float c;
float media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;

printf(La media tra %d e %d e %f fa %f\n, a,b,c,media);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

43

Un esempio: media tra tre numeri interi


int a, b;
float c;
float media;
a=5;
b=7;
c=11;
media=(a+b+c)/3;

//a+b+c: conversione a float e quindi


//la divisione tra float: 7.666667
//valore float assegnato a media!
printf(La media tra %d e %d e %f fa %f\n, a,b,c,media);

7.666667

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

44

Un esempio: media tra tre numeri interi


int a, b, c;
float media;
a=5;
b=7;
c=11;
media=(a+b+c)/3.0;
printf(La media tra %d e %d e %d fa %f\n, a,b,c,media);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

45

Un esempio: media tra tre numeri interi


int a, b, c;
float media;
a=5;
b=7;
c=11;
media=(a+b+c)/3.0;

//conversione di 23 a double
//divisione in double
//conversione del risultato a float
printf(La media tra %d e %d e %d fa %f\n, a,b,c,media);

7.666667

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

46

ESEMPIO DI OVERFLOW
float f;
int x=100000;
f=x*100000;

// operatore * eseguito su int

printf(Risultato = %f, f); // 1410065408 (senza senso!)

ED ESEMPIO DI NON OVERFLOW


float f;
int x=100000;
f=x*100000.0f;

// operatore * eseguito su float

printf(Risultato = %f, f);

// 10000000000

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

47

UN ESEMPIO SEMPLICE?
float a;
a=0.1;
if (a==0.1)
printf(S, uguale\n);
else printf(No, non uguale\n);

PROVARE PER CREDERE

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

48

UNA SEMPLICE VARIANTE?


float a;
a=0.1;
if (a==0.1f)
printf(S, uguale\n);
else printf(No, non uguale\n);

PROVARE PER CREDERE

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

49

COSA SUCCEDE NEL PRIMO CASO


Premessa: 0.110 = 0.000112 = 1.100112*2-4
float:
double:

0 0111011 10011001100110011001100
0 0..0111011 1001100110011001100110011001100....

float a;
a=0.1;

// 0.1 double perde precisione e diventa float

if (a==0.1)

esteso

0 0..0111011 10011001100110011001100110011

double:

0 0..0111011 10011001100110011001100000000

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

50

MORALE
Attenzione ad usare loperatore di confronto == con i tipi non interi
(luguaglianza dovrebbe essere sostituita con lappartenenza
ad un intervallo)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

51

ALTRO AVVERTIMENTO (non per lesame ma per progetti C)


Per motivi legati alle regole di conversione del C, mescolando
interi signed e unsigned il risultato pu essere diverso da quanto
atteso!
Esempio
int x=-20;
unsigned int y=10;
if(x>y)
printf(Assurdo!);

Prof. M. Giacomin

// x convertito a unsigned: positivo alto!!!


// lo stampa!!!

Elementi di Informatica e Programmazione Universit di Brescia

52

Conversione esplicite (casting)


Sintassi
(<tipo>) <espressione>
Significato
Converte il valore dellespressione nel tipo specificato
Esempio
float f, fraz;
f=3.2;
fraz= f (int)f;

Prof. M. Giacomin

// fraz=0.2

Elementi di Informatica e Programmazione Universit di Brescia

53

ESEMPIO 1: forzare la divisione tra float


int dividendo=5, divisore=2;
float quoziente;
quoziente= (float) dividendo / divisore;

// quoziente=2.5

NB: stesso effetto con


quoziente= dividendo / (float) divisore;

oppure
quoziente= (float) dividendo / (float) divisore;

ma non con
quoziente= (float) (dividendo / divisore);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

54

ESEMPIO 2: evitare loverflow


float f;
int x=100000;
int y=100000;
f=(float)x * y;

// operatore * eseguito su float

printf(Risultato = %f, f);

// 10000000000

NB: non funziona con


f= (float) (x*y);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

55

Commento:
perch non usare sempre il tipo pi grande?
Per risparmiare memoria
- es: sistemi embedded
Per velocizzare lesecuzione degli operandi
- es: calcoli in virgola mobile pi lenti dei calcoli tra interi
Gli interi non sempre rappresentati precisamente in virgola mobile
float f=2123456789;
int x=2123456789;
printf(Come int = %d, x);

// 2123456789

printf(Come float = %f, f);

// 2123456768

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

56

ERRORI TIPICI

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

57

ERRORE TIPICO: VERSIONE 1


int n;

La condizione SEMPRE
verificata
per qualunque n!!!

if(2 <= n <=10)


printf(n compreso tra 2 e 10\n);

ERRORE TIPICO: VERSIONE 2


int n;

La condizione non
MAI verificata
per qualunque n!!!

if(-5 <= n <-2)


printf(n compreso tra 2 e 10\n);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

58

Confondere = (operatore di assegnamento)


con == (operatore di uguaglianza)
Esempio 1
if(a=1)
printf(a=1\n);

stampa in ogni caso a=1 e assegna alla variabile a il valore 1


Esempio 2
if(a=0)
printf(a=0\n);

assegna alla variabile a il valore 0 e non esegue la stampa

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

59

Esempio 3
while(n=1){
scanf(%d, &n);

Prof. M. Giacomin

In questo caso il ciclo infinito


(la condizione n=1 sempre vera!)

Elementi di Informatica e Programmazione Universit di Brescia

60

APPENDICE TECNICO
Regole di conversione implicita applicate dal C

NB: non fa parte del programma desame!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

61

Normali conversioni aritmetiche


CASO A: E presente un operando di tipo in virgola mobile
long double
double
float
TIPI INTERI
CASO B: Entrambi gli operandi interi
PASSO 1: Promozione integrale
[signed/unsigned] char
[signed/unsigned] short int

int
unsigned int

int se in grado di includere tutti i valori del tipo di partenza,


altrimenti unsigned int
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

62

PASSO 2: conversione delleventuale operando con tipo pi piccolo


unsigned long int
long int
unsigned int

Eccezione: se long int e unsigned int hanno la stessa


dimensione, nel caso long int e unsigned int
entrambi convertiti a unsigned long int

int
NOTA: assumendo rappresentazione di interi signed in complemento a 2,
la conversione da signed a unsigned viene fatta:
- estendendo il segno se il tipo di arrivo pi grande, poi
- lasciando i bit cos come sono (interpretati come unsigned)
I numeri negativi (bit di segno a 1) diventano positivi grandi!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

63

ESEMPIO: NON CE OVERFLOW!


unsigned short x=200;
unsigned short y=100;
int tot;
tot=x+y;
//300 (+ opera su int)

ESEMPIO: ATTENZIONE A MESCOLARE SIGNED E UNSIGNED!


int x=-20;
unsigned int y=10;
if(x>y)
printf(Assurdo!);

//lo stampa!!!

ESEMPIO SIMILE (ma lesito ben diverso)


short int x=-20;
unsigned short int y=10;
if(x>y)
//si ipotizza che int includa unsigned short int
printf(Assurdo!);
//non lo stampa
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

64

Linguaggio C

Funzioni,
struttura dei programmi,
visibilit e permanenza delle variabili
Universit degli Studi di Brescia
Prof. Massimiliano Giacomin

UN ESEMPIO PILOTA
Scrivere un programma che acquisisce da tastiera un numero intero n
maggiore o uguale a 0 e due numeri in virgola mobile p e q, quindi
calcola e stampa la sommatoria
n

pi
! qi+3
i=0
Vediamo direttamente un possibile pseudocodice

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Pseudocodice 1
ACQUISIZIONE n, p, q;
sommatoria=0;
for(i=0;i<=n; i=i+1)
sommatoria = sommatoria+pi/qi+3;
STAMPA sommatoria

Servono due cicli


per calcolare pi e qi+3

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Pseudocodice 2
ACQUISIZIONE n, p, q;
sommatoria=0;
for(i=0;i<=n; i=i+1)
CALCOLA: potppi
CALCOLA: potqqi+3
sommatoria = sommatoria+potp/potq;
STAMPA sommatoria

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Codice
int n, i, j, k, potp, potq;
float p, q, sommatoria;
scanf(%d, &n);
scanf(%f%f, &p, &q);
sommatoria=0;
for(i=0;i<=n; i=i+1){
potp=1;
for(j=1; j<=i; j++)
potp=potp*p;
potq=1;
for(k=1; k<=i+3; k++)
potq=potq*q;

// potp=pi

// potq=qi+3

sommatoria = sommatoria+potp/potq;
}
printf(La sommatoria risulta %f, sommatoria);

Pseudocodice 1 (REPRISE)
ACQUISIZIONE n, p, q;
sommatoria=0;
for(i=0;i<=n; i=i+1)
sommatoria = sommatoria+pi/qi+3;
STAMPA sommatoria

Tutto sarebbe pi semplice ed elegante con la funzione potenza:


potenza: R*NR ovvero potenza: float*intfloat
Esempio:
potenza(5.5, 2)

Prof. M. Giacomin

restituisce 30.25

Elementi di Informatica e Programmazione Universit di Brescia

Codice ipotetico
int n, i;
float p, q, sommatoria;
scanf(%d, &n);
scanf(%f%f, &p, &q);
sommatoria=0;
for(i=0;i<=n; i=i+1)
sommatoria = sommatoria+potenza(p,i)/potenza(q,i+3);
printf(La sommatoria risulta %f, sommatoria);

vediamo come definire e usare le funzioni


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

dalla matematica (prova intermedia 2012)


Sia data la seguente funzione f reale di variabile reale definita da
ex + 2
)
f (x) = arctan( x
e 1
e2 + 2
Es. 1 + f (2) = 1 + arctan( 2
)
e 1

al linguaggio C
Una funzione ha un nome e:
- riceve in ingresso uno o pi parametri (formali), i cui nomi
sono solo utilizzati come riferimento nella definizione
- esegue un compito specifico
- restituisce un risultato (valore)
Sia i parametri sia il valore restituito hanno ciascuno un tipo
In C, la definizione si esprime con un codice C!
La funzione pu essere chiamata passandole un valore!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

DEFINIZIONE DI FUNZIONI
Tipo del
valore restituito

Parametri formali
(parametri della funzione)

<tipo> <nome_funzione>(<tipo1> <arg1>, , <tipon> <argn>){


<Definizione variabili locali>

return <exp>;

CORPO
DELLA
FUNZIONE

}
Restituisce il valore

Tipo di ritorno void: la funzione non restituisce alcun valore


Lista di parametri vuota o void: la funzione non riceve parametri
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO

Nome della
funzione
float

Parametri formali
(parametri della funzione)

potenza(float b, int e){


int k;
float pot=1;
for(k=1;k<=e;k++)

Tipo del
valore restituito

pot=pot*b;
return pot;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

ESEMPIO

float

potenza(float b, int e){


int k;

Variabili
locali

float pot=1;
for(k=1;k<=e;k++)
pot=pot*b;

CORPO
DELLA
FUNZIONE

return pot;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

ESEMPIO

float

potenza(float b, int e){


int k;
float pot=1;
for(k=1;k<=e;k++)

Tipo del
valore restituito

pot=pot*b;
return pot;
}
Restituisce il valore
(di tipo float)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

CODICE COMPLETO DELLESEMPIO


#include<stdio.h>
#include <stdlib.h>
float potenza(float b, int e){
int k;
float pot=1;
for(k=1;k<=e;k++)
pot=pot*b;
return pot;
}
int main(int argc, char *argv[]){
int n, i;
float p, q, sommatoria;
scanf(%d, &n); scanf(%f%f, &p, &q);
sommatoria=0;
for(i=0;i<=n; i=i+1)
sommatoria = sommatoria+potenza(p,i)/potenza(q,i+3);

return 0;
}

CHIAMATA DI UNA FUNZIONE


Invoca la funzione fornendole una lista di espressioni, dette
parametri attuali o argomenti
Sintassi
<nome_funzione>(<exp1>, , <expn>)
Parametri attuali: valori (r-values) corrispondenti
ai parametri formali nella definizione

Esempio

A= potenza(5.5, 2);

float

potenza(float b, int e){

return pot;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

PASSAGGIO DEI PARAMETRI

A= potenza(5.5, 2);

float potenza(float b, int e){


int k;
float pot=1;
for(k=1;k<=e;k++)
pot=pot*b;
return pot;
}

Prof. M. Giacomin

5.5

PARAMETRI

Elementi di Informatica e Programmazione Universit di Brescia

15

DEFINIZIONE DI VARIABILI LOCALI

A= potenza(5.5, 2);

float potenza(float b, int e){


int k;
float pot=1;
for(k=1;k<=e;k++)
pot=pot*b;
return pot;
}

5.5

PARAMETRI

k
pot

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

ESECUZIONE e ISTRUZIONE return

A= potenza(5.5, 2);

float potenza(float b, int e){


int k;
float pot=1;
for(k=1;k<=e;k++)
pot=pot*b;
return pot;
}

5.5

PARAMETRI

k 3
pot 30.25

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

Conversione degli argomenti


Con la chiamata di una funzione: conversione dei parametri
attuali al tipo dei parametri formali (assegnamento)
ESEMPIO

A= potenza(5.5, 2.5);

float

potenza(float b, int e){

return pot;
}

Conversione del valore restituito


Se listruzione return restituisce un valore di tipo diverso da quello
dichiarato nella funzione, conversione implicita (assegnamento)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

IL PUNTO DI VISTA DEL CHIAMANTE


La chiamata ad una funzione corrisponde ad un operatore e
si trova quindi allinterno di una espressione
<nome_funzione>(<exp1>, , <expn>)
Lesecuzione della funzione corrisponde alla valutazione
delloperatore in una normale valutazione dellespressione!
Non necessariamente il valore restituito viene utilizzato
Esempio
printf(%d%, n);

// expression statement
// numero di caratteri visualizzati

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

19

Nota sui parametri formali


I parametri formali si comportano come variabili locali inizializzate
al momento della chiamata alla funzione
La funzione lavora su una copia dei parametri attuali:
le eventuali modifiche non hanno effetto sui parametri attuali
ESEMPIO
i=5;
A=potenza(2, i);
printf(%d, i);

Prof. M. Giacomin

// 5

float potenza(float b, int e){


float pot=1;
for(;e>0;e--)
pot=pot*b;
return pot;
}

Elementi di Informatica e Programmazione Universit di Brescia

20

ESEMPIO DI FUNZIONE SENZA PARAMETRI


/*acquisisce dallutente un intero maggiore o uguale a zero,
ripetendo lacquisizione se lutente inserisce un negativo */
int scanfnonneg(void){

// OK anche int scanfnonneg(){

int num;
printf(Inserisci un numero maggiore o uguale a 0\n);
scanf(%d, &num);
while(num<0){
printf(numero negativo, reinseriscilo\n);
scanf(%d, &num);
}
return num;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

esempio di utilizzo (1)


/*acquisisce dallutente 10 numeri maggiori o uguali a 0
e ne stampa la somma */
int main(int argc, char *argv[]){
int somma=0, i;
for(i=1;i<=10;i++)
somma+=scanfnonneg();
printf(Somma=%d, somma);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

esempio di utilizzo (2)


/*acquisisce dallutente 10 numeri maggiori o uguali a 0
e stampa la somma di quelli appartenenti a (50,100] */
int main(int argc, char *argv[]){
int somma=0, i, num;
for(i=1;i<=10;i++){
num=scanfnonneg();
if(num>50 && num<=100)
somma+=num;
}
printf(Somma=%d, somma);

}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

esempio di utilizzo errato (2)


/*acquisisce dallutente 10 numeri maggiori o uguali a 0
e stampa la somma di quelli appartenenti a (50,100] */
int main(int argc, char *argv[]){
int somma=0, i, num;
for(i=1;i<=10;i++)
if(scanfnonneg()>50 && scanfnonneg()<=100)
somma+=scanfnonneg();
printf(Somma=%d, somma);

}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

ESEMPIO DI FUNZIONE CHE NON RESTITUISCE VALORI


/*stampa a video un quadrato di n*n asterischi */
void printquadrato(int n){
int r, c;
for(r=1; r<=n; r++){
for(c=1; c<=n; c++)
printf(*);
printf(\n);
}
}

// return non necessario in questo caso

Esempio di chiamata:
printfquadrato(5);
Prof. M. Giacomin

//non ce alcun valore restituito

Elementi di Informatica e Programmazione Universit di Brescia

25

DICHIARAZIONE DI FUNZIONI
Concetto valido per tutti gli oggetti (funzioni e variabili):
- dichiarazione: introduce solo il nome e tipologia di un oggetto
- definizione: crea anche loggetto allocando spazio in memoria
Per poter usare un oggetto, questo deve essere stato prima dichiarato
Nel caso di programma in un solo file, per le variabili definizione
e dichiarazione coincidono
Una funzione pu essere invece essere dichiarata prima di essere
definita: la dichiarazione si ottiene con il suo prototipo
(negli esempi precedenti, le funzioni venivano sempre definite
contestualmente alla loro dichiarazione)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

26

Prototipo di funzioni (1)


Corrisponde alla prima riga della definizione di funzione
(seguito sempre da punto e virgola) e specifica:
- il tipo di ritorno
- il nome della funzione
- la lista di argomenti con i relativi tipi (pu indicare o meno
i relativi nomi, ignorati dal compilatore)
Esempi equivalenti:
float potenza(float b, int e);
float potenza(float, int);
float potenza(float base, int esponente);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

27

Prototipo di funzioni (2)


Quando il compilatore incontra una chiamata a una funzione,
questa deve essere stata dichiarata (altrimenti: assunzioni di
default che possono essere errate):
1) dichiarazione mediante il prototipo, oppure
2) definizione della funzione prima della chiamata
(una definizione funge anche da dichiarazione)
APPROCCIO SCONSIGLIATO (si vedr perch)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

28

ESEMPIO CON LA FUNZIONE POTENZA


float potenza (float, int);

//non necessari nomi parametri

int main(int argc, char *argv[]){


float b;
b= potenza(5.5, 2);

}
float potenza(float x, int n){
int i;
float pot=1;
for(i=1;i<=n;i++)
pot=pot*x;
return pot;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

29

VARIANTE 1
float potenza (float b, int e);

//parametri diversi da def.ne OK

int main(int argc, char *argv[]){


float b;
b= potenza(5.5, 2);

}
float potenza(float x, int n){
int i;
float pot=1;
for(i=1;i<=n;i++)
pot=pot*x;
return pot;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

30

VARIANTE 2 senza prototipo (sconsigliata)


float potenza(float x, int n){
int i;
float pot=1;
for(i=1;i<=n;i++)
pot=pot*x;
return pot;
}
int main(int argc, char *argv[]){
float b;
b= potenza(5.5, 2);

}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

31

E BUONA PRATICA USARE IL PROTOTIPO


Le funzioni possono anche chiamarsi tra loro:
mettere tutte le definizioni prima del main richiede che queste
siano ordinate opportunamente
Se due funzioni si chiamano lun laltra, un ordinamento opportuno
non esiste!
Per programmi di grandi dimensioni, diverse funzioni possono
essere contenute in diversi file: se un file contiene chiamate a
funzioni definite in un altro file, le funzioni devono essere dichiarate

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

32

STRUTTURA DEI PROGRAMMI C

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

33

UN MISTERO SVELATO: il main


int main(int argc, char *argv[]){

return 0;
}

Il main non altro che una funzione!


Tutti i programmi C devono contenere una funzione chiamata main
La funzione main chiamata dal Sistema Operativo quando il
programma viene eseguito

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

34

Argomenti e valore restituito


int main(int argc, char *argv[]){

return 0;
}

Parametri: corrispondono a informazioni passate al programma


Es. in UNIX: ls l prova.txt
Valore restituito di tipo int: pu essere testato dal sistema operativo:
- 0 indica luscita con successo (terminazione normale)
- altro valore: indica situazioni particolari (eccezioni)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

35

STRUTTURA DI UN PROGRAMMA C
int globale1, globale2;

VARIABILI GLOBALI

int main(int argc,){

VARIABILI LOCALI
e PARAMETRI DEL BLOCCO main

int locmain1, locmain2;

}
int f(int p1, float p2){
int loc1, loc2;

{ int bl1;
float bl2;

{ char bll1;

VARIABILI LOCALI
e PARAMETRI DEL BLOCCO f
VARIABILI DEFINITE
IN UN BLOCCO contenuto in blocco f
VARIABILI DEFINITE IN UN
BLOCCO contenuto nel precedente

}
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

36

RAPPRESENTAZIONE BLOCCHI (ESEMPIO PRECEDENTE)


GLOBALE
main

Blocco f
Blocco
Blocco

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

37

GESTIONE DELLE CHIAMATE


Una funzione pu includere una chiamata ad unaltra
funzione (lo abbiamo gi visto con il main!!!)
In ogni chiamata si distinguono due ruoli:
funzione chiamante e funzione chiamata
f2

funzione chiamata (2)

f1

funzione chiamante (2)


funzione chiamata (1)

chiamata 2
chiamata 1
main

Prof. M. Giacomin

funzione chiamante (1)

Elementi di Informatica e Programmazione Universit di Brescia

38

Gestione delle chiamate: record di attivazione (1)

A=potenza(5.5, 2);

RECORD DI
ATTIVAZIONE

main

PARAMETRI
e VARIABILI
LOCALI

AMBIENTE
GLOBALE
Prof. M. Giacomin

MEMORIA
PER VARIABILI
GLOBALI

Elementi di Informatica e Programmazione Universit di Brescia

39

Gestione delle chiamate: record di attivazione (2)


A= potenza(5.5, 2);

RECORD DI
potenza
ATTIVAZIONE

e
k

PARAMETRI
VARIABILI
LOCALI

pot
indirizzo di ritorno

RECORD DI
ATTIVAZIONE

main

PARAMETRI
e VARIABILI
LOCALI

AMBIENTE
GLOBALE
Prof. M. Giacomin

MEMORIA
PER VARIABILI
GLOBALI

Elementi di Informatica e Programmazione Universit di Brescia

40

Gestione delle chiamate: record di attivazione (3)


A= potenza(5.5, 2);

RECORD DI
potenza
ATTIVAZIONE

5.5

PARAMETRI
VARIABILI
LOCALI

pot
indirizzo di ritorno

RECORD DI
ATTIVAZIONE

main

PARAMETRI
e VARIABILI
LOCALI

AMBIENTE
GLOBALE
Prof. M. Giacomin

MEMORIA
PER VARIABILI
GLOBALI

Elementi di Informatica e Programmazione Universit di Brescia

41

Gestione delle chiamate: record di attivazione (4)

return pot;

RECORD DI
potenza
ATTIVAZIONE

5.5

k 3
pot 30.25

PARAMETRI
VARIABILI
LOCALI

indirizzo di ritorno
RECORD DI
ATTIVAZIONE

main

PARAMETRI
e VARIABILI
LOCALI

AMBIENTE
GLOBALE
Prof. M. Giacomin

MEMORIA
PER VARIABILI
GLOBALI

Elementi di Informatica e Programmazione Universit di Brescia

42

Gestione delle chiamate: record di attivazione (5)

return pot;
A= potenza(5.5, 2);

RECORD DI
ATTIVAZIONE

main

A 30.25

AMBIENTE
GLOBALE
Prof. M. Giacomin

PARAMETRI
e VARIABILI
LOCALI
MEMORIA
PER VARIABILI
GLOBALI

Elementi di Informatica e Programmazione Universit di Brescia

43

Gestione delle chiamate: stack di attivazione (0)

int main(){

f1();

}
int f1(){

f2();

f3();

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

44

Gestione delle chiamate: stack di attivazione (1)

main

f1()

AMBIENTE
GLOBALE
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

45

Gestione delle chiamate: stack di attivazione (2)

f1
main

f2()
f1()

AMBIENTE
GLOBALE
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

46

Gestione delle chiamate: stack di attivazione (3)

f2
f1
main

return
f2()
f1()

AMBIENTE
GLOBALE
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

47

Gestione delle chiamate: stack di attivazione (4)

f1
main

f3()
f1()

AMBIENTE
GLOBALE
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

48

Gestione delle chiamate: stack di attivazione (5)

f3
f1
main

return

f3()
f1()

AMBIENTE
GLOBALE
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

49

Gestione delle chiamate: stack di attivazione (6)

f1
main

return
f1()

AMBIENTE
GLOBALE
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

50

Gestione delle chiamate: stack di attivazione (7)

main
AMBIENTE
GLOBALE
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

51

VISIBILITA E PERMANENZA VARIABILI


int x, y;
int main(){
int x;

// x crea un conflitto con altri x?

x=2;

// a quale variabile si riferisce?

y=3;

// a quale variabile si riferisce?

f(3);
}

int f(int x){

// x crea un conflitto con gli altri x?

int z;
x=x+1;

// a quale variabile si riferisce?

}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

52

Note al lucido precedente


Due concetti per le variabili:
- visibilit:
parte del programma da cui una variabile pu essere riferita
- permanenza o tempo di vita:
periodo temporale durante il quale la variabile esiste
(dalla creazione alla distruzione)
Esempio (visibilit):
variabile globale y visibile dal blocco main
Esempio (permanenza):
variabile z locale di f creata quando si chiama f, distrutta
al ritorno da f
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

53

REGOLE DI VISIBILITA (1)


GLOBALE

Blocco1

Blocco2

Prof. M. Giacomin

In un blocco si
vede (si pu
accedere a)
quanto definito
nel blocco e in
quelli che lo
comprendono
(a meno della
regola successiva)

Elementi di Informatica e Programmazione Universit di Brescia

54

REGOLE DI VISIBILITA (2)


GLOBALE

int x;

Blocco1

Blocco2
int x;

Prof. M. Giacomin

Un oggetto
definito in un
blocco B maschera
(rende non visibili)
gli oggetti con lo
stesso nome
definiti nei blocchi
che comprendono B

Elementi di Informatica e Programmazione Universit di Brescia

55

ESEMPIO
VARIABILI GLOBALI
x
i

int x, int i;
int main(int argc,){
int x;
}

f
y

int f(int y){


int i;

x=5;
i=6;
y=7;
}

Prof. M. Giacomin

x
i
y
Elementi di Informatica e Programmazione Universit di Brescia

56

VARIANTE ESEMPIO
INDEFINITA
int main(int argc,){
int x, int i;

}
int f(int y){
int i;

x=5;
i=6;
y=7;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

57

ESEMPIO PILOTA CON VARIABILI OMONIME


#include <stdio.h>
#include <stdlib.h>
float potenza(float, int);
int main(int argc, char* argv[]){
int n, i;
float a, b, sommatoria;
scanf(%d%f%f, &n, &a, &b);
sommatoria=0;
for(i=0;i<=n; i=i+1)
sommatoria = sommatoria+potenza(a,i)/potenza(b,i+3);
printf(La sommatoria risulta %f\n, sommatoria);
return 0;
}
float potenza(float b, int n){
int i;
float a=1;
for(i=1;i<=n;i++)
a=a*b;
return a;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

58

VARIABILI GLOBALI
Permanenza statica
- Definite una sola volta, esistono fino a fine esecuzione programma
(mantenendo lo stesso spazio in memoria)
Visibili ovunque, mascherate da variabili locali omonime (cf. regole)
Consentono comunicazione tra tutte le funzioni (effetti collaterali)
vglob
funzione1{
.
}
Prof. M. Giacomin

funzione2{
.
}

Elementi di Informatica e Programmazione Universit di Brescia

59

ESEMPIO
int globale;

// esiste sempre!

int main(int argc, char *argv[]){


globale=5;
f1();
f2();
printf(%d, globale);
}

// stampa 12

void f1(){
globale=globale+1;
}

// globale=6

void f2(){
globale=globale*2;
}

// globale=12

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

60

Nota
Luso di variabili globali dovrebbe essere limitato a casi specifici
- rendono meno leggibile e comprensibile il codice
- ostacolano il riuso delle funzioni che le riferiscono
Esempio pessimo
int esponente;
float base, potenza;
void potenza();
int main(int argc, char *argv[]){
float x;
base=5.5;
esponente=2;
potenza();
x=potenza;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

61

VARIABILI LOCALI (NON STATIC)


Variabile definita allinterno di un blocco (parametro formale, variabile
locale, variabile definita in un blocco{}): permanenza automatica
- Variabile creata ogni volta che si entra nel blocco in cui
definita, distrutta quando si esce definitivamente dal blocco
valore non conservato tra unentrata nel blocco e la successiva
Esempio
for(i=1;i<=5;i++){
int b1=5;
printf(%d\n, b1);
b1++;
}

Prof. M. Giacomin

//stampa sempre 5

Elementi di Informatica e Programmazione Universit di Brescia

62

Visibili solo nella funzione in cui dichiarate (e in suoi blocchi)


Variabili omonime in record di attivazione distinti sono variabili distinte
int x;

// globale

int main(int argc, char *argv[]){


x=5;
f();
x=x+1;
printf(%d, x);
// stampa 6

}
void f(){
int x=10;
x=x+1;
}
Prof. M. Giacomin

// maschera x globale
// x=11

Elementi di Informatica e Programmazione Universit di Brescia

63

Nota

Le variabili locali in una funzione non interferiscono con


il resto del programma
Variabili locali in una istruzione composta possono essere
usate per migliorare la leggibilit del codice ed evitare
interferenze con il resto del programma

Esempio
// scambio di x e y nascondendo temp
if(){
int temp;
temp=x;
x=y;
y=temp;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

64

VARIABILI LOCALI STATIC


Variabili locali o in un blocco definite con la parola chiave static:
permanenza statica
- Definizione e allocazione memoria effettuata una sola volta,
poi la variabile esiste fino a fine esecuzione programma
occupa lo stesso spazio di memoria fino a fine esecuzione
eventuale inizializzazione (inclusa nella definizione)
effettuata una sola volta
variabili locali/blocco static conservano il valore
dopo luscita dalla funzione/dal blocco
variabili omonime della stessa funzione in record di attivazione
distinti sono la stessa variabile!
Visibilit locale (solo nel blocco in cui vengono dichiarate)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

65

Esempio: variabile definita in un blocco con static


for(i=1;i<=5;i++){
static int b1=5;

// solo la prima iterazione

printf(%d\n, b1);
b1++;
}

Alla prima iterazione b1 inizializzata a 5, si stampa 5


Alla seconda iterazione (inizio) b1 ha il valore 6
alla terza iterazione (inizio) b1 ha il valore 7
ecc. ecc.
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

66

Esempio: variabile locale definita con static


int count;
int main(){
int count;
funzione();
funzione();
}
void funzione( ){
static int count=1;

// solo la prima chiamata

printf(%d, count);

// 1 alla 1a chiamata, 2 alla 2a

count=count+1;

}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

67

ESEMPIO REALE: FUNZIONE CHE MANTIENE GLI ESAMI


/*Funzione che mantiene gli esami superati da uno studente. Se riceve in ingresso:
- intero >=18: inserisce un nuovo esame con la votazione inserita, restituisce 1
- intero = 0: restituisce il numero di esami superati
- intero = 1: restituisce la media (se sono stati superati esami)
*/
float esami(int voto){
static int superati=0;
static int sommavoti=0;
if(voto>=18 && voto<=30){
superati++;
sommavoti+=voto;
return 1;
}
if(voto==0)
return superati;
if(voto==1 && superati!=0)
return ((float)sommavoti)/superati;
return 0;

//eccezione

}
Elementi di Informatica e Programmazione Universit di Brescia

68

NOTE RIASSUNTIVE
Permanenza in memoria (o tempo di vita) :
periodo temporale durante il quale la variabile esiste
(dalla creazione: allocazione di memoria ad essa dedicata
alla distruzione: de-allocazione della memoria)
Visibilit:
parte del programma da cui la variabile pu essere riferita.
Permanenza e Visibilit sono concetti distinti:
- la permanenza si riferisce allo stack di attivazione
- la visibilit si determina staticamente dalla struttura del
programma
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

69

ESERCIZIO INDIVIDUALE
- ESAMINARE IL PROGRAMMA provapermvis
- CERCARE DI INDOVINARE I VALORI
STAMPATI DALLE VARIE printf
- ESEGUIRE IL PROGRAMMA E VERIFICARE
LE PROPRIE RISPOSTE

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

70

SVILUPPARE PROGRAMMI
CON LE FUNZIONI

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

71

Le funzioni non sono solo un puro costrutto del C: possono


semplificare lo sviluppo del codice
Possono essere utilizzate direttamente nella fase di scomposizione
del problema:
1) Emerge lesigenza di una nuova funzione
2) Definire il compito specifico della funzione + scrivere il prototipo
- deve esserci TUTTO quello che serve ad un altro programmatore
per definire la funzione (senza esaminare il chiamante!)
3) Usare le chiamate di funzione
4) La definizione delle funzioni solo alla fine!
Vediamo un esempio:
calcolo del coefficiente binomiale (prossimi lucidi)
Elementi di Informatica e Programmazione Universit di Brescia

72

ESEMPIO
Acquisire dallutente due numeri interi n e k.
Calcolare quindi il coefficiente binomiale

n
n!
=
k k!(n k )!
NB: il coefficiente binomiale corrisponde al numero di insiemi
di k elementi scelti da un insieme prefissato di n elementi

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

73

PASSO 1
int main(int argc, char *argv[]){
int n, k;
unsigned long int binom;
printf("Inserisci n\n");
scanf("%d", &n);
printf("Inserisci k\n");
scanf("%d", &k);
binom=(fattoriale(n)/fattoriale(k))/fattoriale(n-k);
printf("Coefficiente binomiale = %lu\n", binom);

}
Elementi di Informatica e Programmazione Universit di Brescia

74

PASSO 2
unsigned long fattoriale(int num);
int main(int argc, char *argv[]){
int n, k;
unsigned long int binom;
printf("Inserisci n\n");
scanf("%d", &n);
printf("Inserisci k\n");
scanf("%d", &k);
binom=(fattoriale(n)/fattoriale(k))/fattoriale(n-k);
printf("Coefficiente binomiale = %lu\n", binom);

}
Elementi di Informatica e Programmazione Universit di Brescia

75

Se si trova un sottoproblema da risolvere, questo pu essere


delegato ad una funzione: si scrive la chiamata e si progetta
il prototipo
La definizione delle funzioni pu essere rimandata ad una
fase successiva
unsigned long fattoriale (int num){
int i;
unsigned long fatt=1;
for(i=1; i<=num; i++)
fatt=fatt*i;
return fatt;
}

Elementi di Informatica e Programmazione Universit di Brescia

76

VANTAGGI DELLE FUNZIONI NEL CODICE


INFORMATION HIDING:
la funzione chiamante deve conoscere solo il prototipo
LEGGIBILITA
RIUSABILITA
(stessa funzione utilizzabile in programmi diversi)
MODIFICABILITA
(se non si cambia il prototipo, modifiche al corpo della
funzione non hanno impatto sul resto del programma)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

77

BUONE PRATICHE
1) Ogni funzione un compito specifico
2) Scegliere un nome specifico esplicativo per la funzione
ESEMPIO:
una funzione che riceve in ingresso un numero positivo
e controlla se primo va spezzata in due:
- acquisiscipositivo
- primo (controlla se un numero primo)
3) Fattorizzare il pi possibile i compiti in funzioni significative
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

78

Soluzione pi elegante esempio precedente con due funzioni


/* calcola il fattoriale di n */
unsigned long fattoriale (int n);
/*calcola il coefficiente binomiale di n e k*/
unsigned long binomiale (int n, int k);
int main(int argc, char *argv[]){
int n, k;
printf("Inserisci n\n");
scanf("%d", &n);
printf("Inserisci k\n");
scanf("%d", &k);
printf("Coefficiente binomiale = %lu\n", binomiale(n, k));
system("PAUSE");
}

unsigned long fattoriale (int n){


int i;
unsigned long fatt=1;
for(i=1; i<=n; i++)
fatt=fatt*i;
return fatt;
}
unsigned long binomiale (int n, int k){
return (fattoriale(n)/fattoriale(k))/fattoriale(n-k);
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

80

NOTA
Un algoritmo pi efficiente di calcolo del coefficiente binomiale
pu fare uso della seguente equazione:

n
n!
n(n 1) (n k + 1)
=
=
k!
k k!(n k )!
Si pu cambiare lalgoritmo senza riflessi sul main
(LASCIATO PER ESERCIZIO!)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

81

Linguaggio C

puntatori

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin

Lindirizzo, questo sconosciuto


TIPO
Indirizzo

NOME
Valore

0101011110011001
1101011110011111
Indirizzo 0111000000011001
1101011100011101
0110011110011001
0101000111011000
1010011110011001
0101111110000000
0101010010011001

IMPLEMENTAZ.

NB: lindirizzo un valore (rvalue)


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Indirizzo e tipo associato

indirizzo

TIPO

int

count

10

NB: intuitivamente lindirizzo


riferisce o punta a
un oggetto

int *
Il tipo di un indirizzo (che un valore):
<tipo> *
(puntatore a <tipo>)
Motivo: per accedere alloggetto puntato tramite il suo indirizzo,
il C deve conoscerne il tipo!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Operatori & e *
indirizzo

(unari)
int

&count
*indirizzo

count

10

Operatore indirizzo &:


- applicato a operando lvalue, restituisce il suo indirizzo (rvalue)
Operatore asterisco *:
- applicato a indirizzo (rvalue), restituisce oggetto puntato (lvalue)
ESEMPIO
int count=10;
*(&count)=*(&count)+20;
Prof. M. Giacomin

// count=count+20

Elementi di Informatica e Programmazione Universit di Brescia

TUTTO IL RESTO
CONSEGUE DA QUANTO VISTO!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

VARIABILI PUNTATORE
Sono normali variabili, i cui valori sono indirizzi (di altre variabili)
ESEMPIO

500000

countPtr
600000

Rappresentazione
schematica
countPtr

600000

count
10

MEMORIA
CENTRALE
Prof. M. Giacomin

count

10
NB: si dice che countPtr
punta a o si riferisce a
count

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 1
int count=10;
int *countPtr;

Prof. M. Giacomin

countPtr

Elementi di Informatica e Programmazione Universit di Brescia

count

10

Esempio 1
countPtr

int count=10;

count

10

int *countPtr;
countPtr=&count;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 1
countPtr

int count=10;

count *countPtr

20

int *countPtr;
countPtr=&count;
*countPtr = 20; // equivalente a count=20

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Dichiarazione di variabili puntatore


Sintassi
<tipo> *<nomePtr1>, *<nomePtr2>, nomevar1, ;

<tipo> pu essere qualsiasi (nessuna restrizione)


Loperatore * applicato ad un solo nomePtr
Una variabile puntatore pu essere inizializzata
con lindirizzo di unaltra variabile gi definita
Esempio
int count=10, *countPtr=&count;

NB: ogni variabile puntatore pu fare riferimento solo ad oggetti dello


stesso tipo con cui stata dichiarata (tipo del riferimento)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

ESEMPIO COMPLETO
int count, *countPtr=&count;
int count2, *countPtr2=&count2;
*countPtr=20;
printf( %d\n , count);

// stampa 20

printf( %d\n , *countPtr);

// stampa 20

printf( %p\n , countPtr);

// stampa un indirizzo

printf( %p\n , &*countPtr);

// stampa stesso indirizzo

printf( %p\n , *&countPtr);

// idem

*countPtr2=*countPtr;

// count2=count (==20)

*countPtr2=30;

// count2=30 (count==20)

countPtr2=countPtr;

// count2==30, count==20

*countPtr2=40;

// count2==30, count=40

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

UNO DEGLI USI DEI PUNTATORI


Puntatori usati come argomenti delle funzioni:
il passaggio per riferimento dei parametri

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

Il passaggio dei parametri nei linguaggi di programmazione


PARAMETRI FORMALI
modulo chiamato

PARAMETRI ATTUALI
modulo chiamante

per valore

CHIAMATA

indirizzo

per
indirizzo

per valore

AGGIORNAMENTI

per
indirizzo

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

Spiegazione lucido precedente


Alcuni linguaggi prevedono due modalit di passaggio dei parametri:
- per valore: i parametri attuali sono copiati nelle variabili della
procedura corrispondenti ai suoi parametri formali,
la procedura quindi non li modifica
- per indirizzo (detta anche per riferimento):
la zona di memoria del parametro formale non
contiene il valore, ma lindirizzo del parametro
attuale; tutte le operazioni sul parametro formale
sono in realt effettuate sul parametro attuale
In C disponibile solo il passaggio per valore

Docente: M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

Puntatori e chiamata per riferimento delle funzioni (1)

CHIAMANTE

F.NE CHIAMATA
int funz(int *punt, )

punt
int a;
.
funz(&a, );
PASSAGGIO PER VALORE,
MA DI UN INDIRIZZO!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

Puntatori e chiamata per riferimento delle funzioni (2)

CHIAMANTE

F.NE CHIAMATA
int funz(int *punt, )

punt
int a;
.
funz(&a, );

.
*punt=10;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

Puntatori e chiamata per riferimento delle funzioni (3)

CHIAMANTE

F.NE CHIAMATA
int funz(int *punt, )

10

punt

int a;
.
funz(&a, );

.
*punt=10;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

PASSAGGIO PER RIFERIMENTO DI PARAMETRI IN C


Un parametro formale della funzione definito come puntatore
La funzione chiamante passa lindirizzo di una variabile
La funzione chiamata pu modificare la variabile della funzione
chiamante utilizzando loperatore * applicato al relativo indirizzo

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Un motivo per passare per riferimento i parametri


Per modificare pi variabili della funzione chiamante
- il solo valore restituito pu essere insufficiente
ESEMPIO 1
void decomponi (float a, int *p_intera, float *p_frazionaria){
*p_intera= (int)a;
*p_frazionaria=a- *p_intera;
}

Esempio
di chiamata
Prof. M. Giacomin

float f=3.5, pf;


int pi;
decomponi(f, &pi, &pf);

Elementi di Informatica e Programmazione Universit di Brescia

19

ESEMPIO 2
void scambia (int *a, int *b){
int temp;
temp=*a;
*a=*b;
*b=temp;
}

e quindi per scambiare i valori di due variabili intere x e y:


scambia (&x, &y);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

ESEMPIO 3 E MISTERO SVELATO


int i, j;
printf(Inserire due numeri interi\n);
scanf(%d%d, &i, &j);

UNA VARIANTE EQUIVALENTE PER CAPIRE


int i, j;
int *p;
p=&j;
printf(Inserire due numeri interi\n);
scanf(%d%d, &i, p);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

Linguaggio C
tipi di dati definiti dallutente: enumerazioni

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Tipi di dati in C
Semplici

Strutturati

Predefiniti

char, int, float,


double

Definiti
dallutente

enum

struct, array

Tipi di dati semplici: le variabili contengono informazioni


logicamente indivisibili
Tipi di dati strutturati: informazioni scomponibili in pi componenti
(es: i giocatori di una squadra di calcio)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Chiarimento IMPORANTE sui concetti fondamentali


VARIABILI DI
TIPO CASTELLO

TIPO DI
DATO CASTELLO

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Enumerazione
Tipo che prevede un insieme specificato di valori ammissibili,
chiamati costanti di enumerazione
il tipo definito dallutente

Esempio:
enum squadre {Inter, Juventus, Milan};
enum nomi {Giovanni, Luca, Marco, Matteo};
int main(){
enum squadre squadrona; //variabile di tipo enum squadre
squadrona=Milan;
enum nomi Ev_1=Giovanni;

if(squadrona==Juventus)
printf( Rilevato errore\n );

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Dichiarazione di un tipo enum


enum <nometipo> {<lista valori>};

definisce il tipo enum <nometipo> quindi per definire variabili:


enum <nometipo> <nomevariabile1>, <nomevariabile2>;

Dichiarazione di un tipo enum e contestualmente di variabili


si puo anche omettere

enum <nometipo> {<lista valori>} <var1>, <var2>;

Esempio
enum squadre {Inter, Juventus, Milan} squadrina, squadrona;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Enumerazioni e interi
In realt, il C tratta lenumerazione come una ridefinizione di int:
le costanti di enumerazione rappresentano interi
Se non si specifica nulla, le costanti cominciano da 0 e rappresentano
valori consecutivi. E possibile specificare i valori di una o pi costanti
Esempi:

enum mesi {GEN=1, FEB, MAR, APR, MAG, GIU, LUG, AGO, SET};
enum nomi {Giovanni=3, Luca, Marco, Matteo=3};

Di conseguenza, sono disponibili gli operatori degli interi, p.es.


== !=
>
ecc.
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio puramente didattico


enum squadre {Inter, Juventus, Milan};
int main(){
enum squadre squadragen;
int a=0;
for(squadragen=Inter; squadragen<=Milan; squadragen++){
printf(%d, squadragen);
a=a+squadragen;

// stampa 0, 1, 2
// non ha molto senso ma vabbe

}
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Dichiarazione di tipi e struttura del programma C


Direttive include
Definizione di tipi
Prototipi delle funzioni definite dallutente
Definizione del main
Definizione delle funzioni definite dalutente
In questo modo i tipi sono:
Utilizzabili nei parametri delle funzioni
Visibili allinterno di tutte le funzioni (per definire variabili)
Tipo definito dentro una funzione: visibilit nella sola funzione
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Linguaggio C
tipi di dati definiti dallutente: strutture

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

STRUTTURE
Struttura: collezione di valori, anche di tipo diverso tra loro
(tipicamente concettualmente collegati)
Esempio: vogliamo rappresentare (non disegnare, ma
memorizzare e gestire) figure geometriche in due dimensioni (in
un piano):
- un punto rappresentato da due coordinate (float) x, y
- un cerchio da un centro (punto) e da un raggio (float)
- un rettangolo pu essere rappresentato da due punti
- ecc. ecc.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO SEMPLICE (punto nel piano cartesiano)


il tipo definito dallutente
MEMBRI (CAMPI) DELLA STRUTTURA

struct punto{
float
x;
float
y;
};

struct punto p1;


struct punto p2;

Definizione
del tipo
struct
punto

punto
float x
float y

Definizione variabili p1 e p2
p1

p1.x

p2

p2.x

p1.y

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

p2.y

ESEMPIO SEMPLICE (punto nel piano cartesiano)


il tipo definito dallutente
MEMBRI (CAMPI) DELLA STRUTTURA

struct punto{
float
x;
float
y;
};

Definizione
del tipo
struct
punto

struct punto p1;


struct punto p2;

Prof. M. Giacomin

float x
float y

Definizione variabili p1 e p2
p1

p1.x=0.5;
p1.y=3;
p2.x=2*p1.x;

punto

Assegnamenti

0.5
3

p1.x

p2

p2.x

p1.y

Elementi di Informatica e Programmazione Universit di Brescia

p2.y

Definizione di tipi struct


struct <nome_struttura>{
<definizione campo 1>;

Attenzione:
concluso da
punto e virgola

};

Struttura definita da:


- insieme finito di elementi, detti membri o campi
- ogni campo:
> ha un tipo specifico (pu essere qualunque)
> identificato da un nome
- nomi univoci allinterno di una struttura
NB: il tipo definito
struct <nome_struttura>
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Nota
Ovviamente ciascun campo pu essere di qualunque tipo e
non necessariamente i campi sono tutti dello stesso tipo!
struct puntocolorato{
float

x;

float

y;

int colore;

// scala di grigi

};

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Definizione di variabili (di tipo struttura)


Niente di nuovo sotto il sole
struct <nome_struttura> <identificatore1>, ;

Vengono create le variabili di nome <identificatore1>,


tutte del tipo struct <nome_struttura>
ATTENZIONE
La definizione di un tipo struct <nome_struttura> ben distinta
dalla definizione di variabili di tipo struct <nome_struttura>

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Operatore di selezione .
Data una variabile struttura v:
v.<nomecampo>

ritorna il campo indicato, che una variabile del tipo corrispondente

Operatore di assegnamento tra strutture


Date due variabili struttura v1 e v2:
v1=v2;

copia byte a byte tutta larea di memoria (tutti i campi) di v2 in v1


v2
v1
NB: v1 e v2 devono essere dello
stesso tipo!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

NB: Operatori di confronto == e != non disponibili per le strutture


(confronto byte a byte non affidabile: contenuto dei buchi
per allineamento campi indefinito)

int
char

0
200
10
?

0
?

200
10
??

SOLUZIONE: effettuare il confronto campo per campo!


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO FIGURE GEOMETRICHE (1)


struct punto{
float

x;

float

y;

};

ad
struct rettangolo{
struct punto bs;
struct punto ad;

bs

};
struct cerchio{
struct punto centro;
float raggio;
};
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

ESEMPIO FIGURE GEOMETRICHE (2)


int main(){
struct rettangolo r1;
struct rettangolo r2;
struct cerchio c1;
r1.bs.x=1;
r1.bs.y=2;
r1.ad.x=6.5;
r1.ad.y=8;
r2=r1;
c1.raggio=5.6;
c1.centro.x=2;
c1.centro.y=3;

}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

Inizializzazione di variabili di tipo struttura


Possono essere inizializzate con una serie di valori tra parentesi graffe
struct punto p1={0.5, 3};

//assegnati ai campi nellordine

Anche per strutture pi complesse, p.es.


int main(){
struct rettangolo r1={ {1,2}, {6.5,8} };

ATTENZIONE: assegnamento inizializzazione!


int main(){
struct punto p1;
p1={0.5, 3};
Prof. M. Giacomin

//ERRORE

Elementi di Informatica e Programmazione Universit di Brescia

12

Definizione congiunta di tipo e di variabili


Definizione di variabili struttura con dichiarazione del tipo
incorporata
opzionale

struct puntocolorato{
float

x;

float

y;

int colore;
} p1, p2;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

STRUTTURE E FUNZIONI (1)


Dato che disponibile lassegnamento tra strutture, tutto normale:
- variabili di tipo struttura possono essere parametri passati per valore
- una funzione pu restituire valori di tipo struttura
ESEMPIO
struct rettangolo quadratocircoscritto(struct cerchio c){
struct rettangolo rext;
rext.bs.x=c.centro.x-c.raggio;
rext.bs.y=c.centro.y-c.raggio;
rext.ad.x=c.centro.x+c.raggio;
rext.ad.y=c.centro.y+c.raggio;
return rext;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

ESEMPIO (continua)
int main(){
struct cerchio c1={{10,5},{3}};
struct rettangolo r;
r=quadratocircoscritto(c1);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

STRUTTURE E FUNZIONI (2)


Per evitare copia intera struttura (che comporta consumo di tempo e
memoria): passarla per riferimento (passare il suo puntatore)
ESEMPIO
float arearettangolo(struct rettangolo *pr){
float base, altezza;
base=(*pr).ad.x-(*pr).bs.x;
altezza=(*pr).ad.y-(*pr).bs.y;
return base*altezza;
}

area=arearettangolo(&rett); //rett di tipo struct rettangolo


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

STRUTTURE E PUNTATORI
Loperatore puntatore a struttura o freccia semplifica laccesso
ad un campo attraverso un puntatore:
strPtr->campo equivalente a (*strPtr).campo
VARIANTE EQUIVALENTE ESEMPIO PRECEDENTE
float arearettangolo(struct rettangolo *pr){
float base, altezza;
base=(pr->ad).x-(pr->bs).x;
altezza=(pr->ad).y-(pr->bs).y;
return base*altezza;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

Linguaggio C
tipi di dato definiti dallutente: vettori

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Concetti generali
Variabili capaci di memorizzare un singolo valore (anche aggregato)
non sono sufficienti per tutti gli scopi
Esempio: programma per gestire un campionato di calcio con un
numero generico di squadre: non basta la struttura squadra
- si dovrebbero definire variabili sq1, sq2, , sq60
- e se voglio meno squadre? E se ne voglio di pi?
- prima o poi si dovranno ordinare le squadre (classifica):
come riferire la singola squadra?
Serve un tipo di dato che aggreghi pi elementi dello stesso tipo
e permetta il riferimento dellelemento i-esimo
uso di un vettore (array)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

I vettori (array)
Un esempio
int vettore1[20];

Variabile costituita da sequenza


di valori dello stesso tipo (int)

int vettore2[20];

0
vettore1 ?
0
vettore2 ?

Prof. M. Giacomin

19

? ? ? ? ? ? ? ? ? ? ?
1

19

? ? ? ? ? ? ? ? ? ? ?

Elementi di Informatica e Programmazione Universit di Brescia

I vettori (array)
Un esempio
int vettore1[20];

Variabile costituita da sequenza


di valori dello stesso tipo (int)

int vettore2[20];

0
vettore1 ?
0
vettore2 ?

19

? ? ? ? ? ? ? ? ? ? ?
1

19

? ? ? ? ? ? ? ? ? ? ?

vettore1[0]=5;
vettore2[19]=-6;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

I vettori (array)
Un esempio
int vettore1[20];

Variabile costituita da sequenza


di valori dello stesso tipo (int)

int vettore2[20];

0
vettore1 5
0
vettore2 ?

...

19

? ? ? ? ? ? ? ? ? ? ?
1

...

19

? ? ? ? ? ? ? ? ? ? -6

vettore1[0]=5;
vettore2[19]=-6;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

I vettori (array)
Un esempio
int vettore1[20];

Variabile costituita da sequenza


di valori dello stesso tipo (int)

int vettore2[20];

0
vettore1 5
0
vettore2 ?

19

? ? ? ? ? ? ? ? ? ? ?
1

...

19

? ? ? ? ? ? ? ? ? ? -6

a = vettore1[0];

Prof. M. Giacomin

...

Elementi di Informatica e Programmazione Universit di Brescia

In generale
Vettore: lista ordinata di elementi dello stesso tipo (qualunque!)
Definizione di una variabile vettore:
<tipo><identificatore>[<dimensione>];

In pratica, definizione singolo elemento aggiungendo [<dimensione>]


I suoi elementi:
- sono variabili di tipo <tipo>
- sono identificati da un indice i (intero o espressione intera)
compreso tra 0 e dimensione -1
- sono denotati come <identificatore>[i] dove i corrisponde
allindice (questa operazione si dice indicizzazione del vettore)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Il costruttore array non definisce alcun operatore specifico,


ad eccezione dellindicizzazione [] (es: assegnamento tra vettori non
ammesso, il confronto non ha il senso atteso lo vedremo)
Gli elementi del vettore sono variabili del relativo tipo e per essi
sono disponibili tutti gli operatori disponibili per quel tipo
(es. vettore di int: assegnamento, confronto, somma, ecc.)
Esempio
enum nomi{Luca, Paolo, Giovanni, Matteo};
enum nomi amici[10];
amici[0]=Luca;

if(amici[3]>Paolo)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESERCIZIO 1
Definire un vettore v capace di memorizzare 10 interi.
Memorizzare quindi nel vettore gli interi da 1 a 10.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESERCIZIO 1
Definire un vettore v capace di memorizzare 10 interi.
Memorizzare quindi nel vettore gli interi da 1 a 10.
int v[10];
for(i=0; i<10; i++)
v[i]=i+1;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

ESERCIZIO 2
Sviluppare un programma che acquisisca dallutente un vettore
di 10 interi. Successivamente, ne calcoli il massimo e il minimo.
Infine, stampi gli elementi del vettore, il massimo e il minimo.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

Scomposizione
ACQUISIZIONE:
user un ciclo per acquisire i 10 numeri (indice i da 0 a 9)
CALCOLO massimo e minimo:
user un ciclo per confrontare due variabili max e min con
tutti gli elementi del vettore.
Problema: con quali valori inizializzo max e min?
Posso inizializzarli con vettore[0]
STAMPA:
user un ciclo per stampare i 10 numeri (indice i da 0 a 9)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

Possiamo sviluppare direttamente il codice


int v[10], i, max, min;
for(i=0; i<10; i++)
scanf( %d , &v[i]);
max=v[0];
min=v[0];
for(i=1; i<10; i++){
if(v[i]>max)
max=v[i];
if(v[i]<min)
min=v[i];
}
printf( Elementi del vettore: );
for(i=0; i<10; i++)
printf( %d\n , v[i]);
printf Massimo=%d, minimo=%d\n , max, min);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

ESERCIZIO 3
Sviluppare un programma che acquisisce dallutente al massimo 50
numeri interi (interrompendo lacquisizione se viene inserito
il numero 0), li memorizza in un vettore vet_1 e produce un vettore
vet_2 che li contiene in ordine inverso.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

ESERCIZIO 3
Sviluppare un programma che acquisisce dallutente al massimo 50
numeri interi (interrompendo lacquisizione se viene inserito
il numero 0), li memorizza in un vettore vet_1 e produce un vettore
vet_2 che li contiene in ordine inverso.
Algoritmo (per la parte di inversione)
vet_1

...

50

...

50

4 1 5 2
i=0 i=1

vet_2

1 4
3-i

Prof. M. Giacomin

3-i

Elementi di Informatica e Programmazione Universit di Brescia

15

ESERCIZIO 3
Sviluppare un programma che acquisisce dallutente al massimo 50
numeri interi (interrompendo lacquisizione se viene inserito
il numero 0), li memorizza in un vettore vet_1 e produce un vettore
vet_2 che li contiene in ordine inverso.
Algoritmo (per la parte di inversione)
vet_1

...

50

...

50

4 1 5 2
i=0 i=1

vet_2

1 4
3-i

3-i

Supponiamo n sia lultima posizione del vettore (3 in questo caso):


for(i=0; i<=n; i++)
vet_2[n-i]=vet_1[i];
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

printf("Inserisci al massimo 50 numeri positivi (0 per terminare)\n");


i=0;

// prossima posizione libera da occupare

do{
scanf("%d", &num);
if(num!=0){
vet_1[i]=num;
i++;
}
} while(num!=0 && i<50);
n=i-1; //ora n indica l ultima posizione occupata del vettore
for(i=0; i<=n; i++)
vet_2[n-i]=vet_1[i];
printf("Vettore invertito\n");
for(i=0; i<=n; i++)
printf("%d\n", vet_2[i]);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

ESERCIZIO 4
Sviluppare un programma che acquisisca da tastiera due array
contenenti 10 numeri interi (int v1[10], int v2[10]),
assicurandosi (per ogni array) che lutente non inserisca un
numero gi inserito (in questo caso, ripetere lacquisizione
di ogni elemento che sia gi stato inserito).
Si trovino quindi tutti gli elementi comuni ad entrambi gli array
e si stampi un messaggio indicante, per ogni elemento comune,
lindice occupato nel primo array e nel secondo.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

Acquisizione di un vettore con esclusione di numeri gi inseriti


for(i=0; i<10; i++){
do
scanf( %d , &num);
while(<numero ripetuto>);

Acquisisci in num un numero


che non sia gi stato inserito

v1[i]=num;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

19

Acquisizione di un vettore con esclusione di numeri gi inseriti


for(i=0; i<10; i++){
do

Acquisisci in num un numero


che non sia gi stato inserito

scanf( %d , &num);
while(<numero ripetuto>);
v1[i]=num;
}

for(i=0; i<10; i++){


do{
scanf( %d , &num);
ripetuto=0;

Raffiniamo il
codice in modo da
calcolare nella variabile
ripetuto la condizione da
verificare

for(j=0; j<i; j++)


if(v1[j]==num) ripetuto=1;
}while(ripetuto);
v1[i]=num;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

Identificazione degli elementi in comune tra v1 e v2


Per ogni elemento v1[i]

con i=0, 9

- scorri tutti gli elementi v2[j] con j=0..9


- se v1[i]= v2[j] allora stampa messaggio

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

Identificazione degli elementi in comune tra v1 e v2


Per ogni elemento v1[i]

con i=0, 9

- scorri tutti gli elementi v2[j] con j=0..9


- se v1[i]= v2[j] allora stampa messaggio

for(i=0;i<10;i++)
for(j=0; j<10; j++)
if(v1[i]==v2[j])
printf("Elemento in comune %d, in posizione %d e %d\n", v1[i], i, j);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

#include <stdio.h>

IL CODICE COMPLETO (SENZA FUNZIONI)

#include <stdlib.h>
int main(int argc, char *argv[]){
int v1[10], v2[10];
int i, j, comune;
printf("Inserisci il secondo vettore (10 numeri interi)\n");

int num;

for(i=0;i<10;i++){
do{

printf("Inserisci il primo vettore (10 numeri interi)\n");

scanf("%d",&num);

for(i=0;i<10;i++){

comune=0;

do{

for(j=0; j<i; j++)

scanf("%d",&num);

if(v2[j]==num)

comune=0;
for(j=0; j<i; j++)

comune=1;

if(v1[j]==num)

}while(comune);
printf("Inserito numero %d\n", num);

comune=1;
}while(comune);

v2[i]=num;

printf("Inserito numero %d\n", num);

v1[i]=num;
for(i=0;i<10;i++)

for(j=0; j<10; j++)


if(v1[i]==v2[j])
printf("Elemento in comune %d, in posizione %d e %d\n", v1[i], i, j);
system("PAUSE");
return 0;
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

Inizializzazione di un vettore
La definizione di un vettore lascia i valori dei suoi elementi indefiniti
Per definire e inizializzare un vettore:
int vett[]={-10, 11, 4, 3};

int vett[10]={-10, 11, 4, 3};

/* equivale a

/* equivale a

int vett[4];
vett[0]=-10;
vett[1]=11;
vett[2]=4;
vett[3]=3;
*/

int vett[10];
vett[0]=-10;
vett[1]=11;
vett[2]=4;
vett[3]=3;
vett[4]=0;
vett[5]=0;

vett[9]=0;
*/

ATTENZIONE
Inizializzazione, non assegnamento (che tra laltro non esiste)!
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

Errore comune nelluso di vettori


Dimenticare che le posizioni sono numerate da 0 a dimensione-1:
int i;
int vett[10];
for(i=1; i<=10; i++)

//vett[0] non utilizzato, vett[10] non esiste

vett[i]=i;

Il codice corretto :
int i;
int vett[10];
for(i=0; i<10; i++)
vett[i]=i;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

Nota
La dimensione di un vettore fissa: compito del programmatore
fare in modo di riferirsi a celle che compongono il vettore
(ovvero, fare in modo che se si usa v[i] sia 0 i dimensione-1)
Esempio
int vett[20], i;
for(i=1; i<=20; i++)
vett[i]=0;

Prof. M. Giacomin

Quando i 20, lo 0 potrebbe


finire nellarea di memoria
di i e quindi portare a un ciclo
infinito! Se si fortunati si
ha invece errore a run-time

Elementi di Informatica e Programmazione Universit di Brescia

26

UN CASO PARTICOLARE DI VETTORI: STRINGHE


Nel C le stringhe vengono rappresentate come array di caratteri,
il cui ultimo elemento il carattere \0 (carattere il cui codice
ASCII 0) che indica la fine della stringa
Esempio
char stringa[30]={N,e,l, ,m,e,z,z,o, ,d,e,l, ,c,a,m,m,i,n,\0};

0 1 2 3 4
stringa N e l m

18 19 20
i n 0

29
0

stringa[20]=o;
stringa[21]=\0;

Prof. M. Giacomin

//con codice ASCII, equivale a

stringa[21]=0;

Elementi di Informatica e Programmazione Universit di Brescia

27

INIZIALIZZAZIONE DI UN VETTORE CON UNA STRINGA


char stringa[30]={N,e,l, ,m,e,z,z,o, ,d,e,l, ,c,a,m,m,i,n,\0};

si pu anche scrivere come


char stringa[30]= Nel mezzo del cammin ;

// \0 viene aggiunto

mentre questo errato:


char stringa[30]=Nel mezzo del cammin;

Esempio con dimensione implicita:


char stringa2[]= Petter Northug ;

0 1 2 3 4
stringa2 P e t t e
Prof. M. Giacomin

// vettore di 15 elementi!

12 13 14
u g \0

Elementi di Informatica e Programmazione Universit di Brescia

28

ESERCIZIO 5
Supponendo che il vettore
char stringa[20];

contenga una stringa di lunghezza ignota, sviluppare il codice per


determinarne la lunghezza (numero di caratteri \0 escluso).

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

29

ESERCIZIO 5
Supponendo che il vettore
char stringa[20];

contenga una stringa di lunghezza ignota, sviluppare il codice per


determinarne la lunghezza (numero di caratteri \0 escluso).
for(i=0; i<20 && stringa[i]!= \0 ; i++);
//calcola la lunghezza della parola inserita (in i)

printf(lunghezza=%d\n, i);

Prof. M. Giacomin

0 lo stesso, non 0!

Elementi di Informatica e Programmazione Universit di Brescia

30

Vettori multidimensionali
I vettori possono avere pi di un indice
Esempio tipico: rappresentazione di matrici (o tabelle)
int a[3][4];

Prof. M. Giacomin

a[0][0]

a[0][1]

a[0][2]

a[0][3]

a[1][0]

a[1][1]

a[1][2]

a[1][3]

a[2][0]

a[2][1]

a[2][2]

a[2][3]

Elementi di Informatica e Programmazione Universit di Brescia

31

Esempio: acquisizione di una matrice da tastiera


int matrice[4][10];
int i, j;
for(i=0; i<4; i++)
for(j=0;j<10;j++){

\\ per ogni riga da 0 a 3


\\ acquisisci le colonne da 0 a 9

printf( Inserisci l elemento matrice[%d][%d]\n , i, j);


scanf( %d , &matrice[i][j]);
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

32

Inizializzazione di una matrice


Ogni riga tra parentesi graffe
Elementi insufficienti per una riga: i rimanenti inizializzati a 0
Elementi in una sola parentesi graffa: riempite le righe dalla prima
int a1[2][3]={{1, 2}, {4}};

int a2[2][3]={1, 2, 3, 4, 5};

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

33

Linguaggio C
vettori, puntatori, funzioni, strutture

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin

SCHEMA DELLA LEZIONE


RELAZIONE TRA
VETTORI E PUNTATORI
(e le stringhe letterali come caso particolare di vettori)
VETTORI E FUNZIONI
VETTORI E STRUTTURE
AVVISO: la lezione probabilmente risulter
SEMPLICE E RIEPILOGATIVA, per coloro che hanno capito
e riguardato gli argomenti spiegati fino a questo punto del corso
INCOMPRENSIBILE, per gli altri
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

VETTORI E PUNTATORI: TRE CONCETTI

1)

Dato un vettore, ad esempio


int v[5];

il suo nome indica lindirizzo del primo elemento (costante)

ESEMPIO
0
int v[]={1,5,2,3,2};
int *p;
p=v;

Prof. M. Giacomin

1 5 2 3 2
v
p

Elementi di Informatica e Programmazione Universit di Brescia

VETTORI E PUNTATORI: TRE CONCETTI

2) Ad un indirizzo p possibile sommare (e sottrarre) interi:


p+i (dove i intero) indica lindirizzo spostato in avanti
di i elementi rispetto a p

ESEMPIO
0
int v[]={1,5,2,3,2};
int *p=v;
*(p+2)=5;

// v[2]=5;

1 5 2 3 2
v
p

p+2
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

VETTORI E PUNTATORI: TRE CONCETTI

3)

Lespressione
v[i]

equivalente a *(v+i)
ESEMPIO
int v[]={1,5,2,3,2};
int *p=v;

Prof. M. Giacomin

v[2]=5;

// *(v+2)=5

p[2]=5;

// *(p+2)=5

Elementi di Informatica e Programmazione Universit di Brescia

ARITMETICA DEI PUNTATORI


Somma p+i / sottrazione p-i di un indirizzo con un intero:
avanzamento/spostamento indietro di i elementi
[operatori applicabili: +, -, +=, -=, ++, --]
Differenza p1-p2 tra due indirizzi:
distanza tra i due puntatori misurata in numero di elementi
Confronto >, >=, <, <= tra due indirizzi:
confronto rispetto alla posizione in un vettore dei rispettivi
elementi puntati

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO COMPLETO
int v[6]={1, 2, 3, 4, 5, 6};
int distanza, *vPtr;
vPtr=v;

// equivale a vPtr=&v[0];

vPtr+=2;

// vPtr punta a v[2]

vPtr++;

// vPtr punta a v[3]

*(vPtr+1)=20;

// v[4]=20

vPtr[2]=30;

// v[5]=30

distanza=vPtr-v;

// distanza=3

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ALTRO ESEMPIO
int i;
char s1[10]=G. Gullo;
char s2[10];
char *s3, *s4;
s2=G. Gullo;

// ERRORE: s2 puntatore costante!

s3=s1;

// LECITO (s3 punta a s1[0])

s2=s3;

// ERRORE: s2 puntatore costante!

for(i=0;i<10;i++)
s2[i]=s1[i];

// cos si copiano GLI ELEMENTI del


// vettore s1 nel vettore s2

for(s3=s1,s4=s2;*s3!=\0;s3++,s4++)
*s4=*s3;
*s4=*s3;
Prof. M. Giacomin

//o anche cos

//copia \0
Elementi di Informatica e Programmazione Universit di Brescia

STRINGHE LETTERALI
A parte il caso dellinizializzazione di un vettore di char,
Mela

indica lindirizzo (del primo el.) di un array di caratteri costante


0 1 2 3 4
M e l a \0

Mela

GIOCHINO: trova le differenze e le uguaglianze


\0

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPIO
char *s = aBETE;

// inizializzazione

char r[] = aBETE;

// inizializzazione

r = aLBERO;

// ERRORE assegnamento: r costante

s = aLBERO;

// OK

r[0]=A;

// OK

s[0]=A;

// ERRATO: COMPORTAM. INDEFINITO


// (stringa letterale costante)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

Stampa e acquisizione di stringhe con printf e scanf


printf e scanf:
- hanno come primo argomento un indirizzo char* (della stringa)
- possono stampare e acquisire stringhe, indicate da %s che deve
corrispondere allindirizzo char* della stringa da stampare/acquisire
NB: in realt scanf legge parole, ovvero stringhe senza spazi)
char str[]=%s, stringa[20]=Mela\n;
printf(Mela\n);

// un argomento di tipo char*

printf(%s, Mela\n);

// due argomenti di tipo char*

printf(str, stringa);

// due argomenti di tipo char*

scanf( %s , stringa);

// non si usa & n []

printf( %s\n , stringa);

// non si usa & n []

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

VETTORI E FUNZIONI
I vettori possono essere passati per riferimento: per specificare
che un parametro formale un vettore, si aggiunge []
Esempio
void modificavett (int v[], int lung){
int i;
for(i=0; i<lung; i++)
v[i]=v[i]*10;
}

La chiamata si effettua passando il nome del vettore


modificavett(vettore, 10);
Prof. M. Giacomin

//vettore ha 10 elementi

Elementi di Informatica e Programmazione Universit di Brescia

12

COSA SUCCEDE IN REALTA


Scrivere int v[] equivale a scrivere int *v, ricordare inoltre
che v[i] equivale a *(v+i)
Definizione equivalente della funzione
void modificavett (int *v, int lung){
int i;
for(i=0; i<lung; i++)
v[i]=v[i]*10;
}

La chiamata si effettua passando lindirizzo del primo elemento


modificavett(vettore, 10);
Prof. M. Giacomin

//vettore ha 10 elementi

Elementi di Informatica e Programmazione Universit di Brescia

13

Passaggio di vettori multidimensionali


Come i vettori unidimensionali, vengono passati per indirizzo
Alla funzione occorre passare tutte le dimensioni tranne la prima
(necessarie al C per risolvere lindicizzazione!)
Matrice a 3 colonne!

Esempio

void stampamatrice (int m[][3], int righe){


int i, j;
for(i=0; i<righe; i++){
for(j=0; j<3; j++)
printf( %d , m[i][j]);
printf( \n );
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

VETTORI E STRUTTURE (1)


I vettori possono essere elementi di strutture
ESEMPIO
struct studente{
int matricola;
char nome[30];
char cognome[30];
int num_esami;
int voti[30];

NB: ad una variabile di tipo


struct studente viene riservato
spazio per:
- 1 int (matricola)
- 30 char (nome)
- 30 char (cognome)
- 1 int (num_esami)
- 30 int (voti)

};
struct studente stud1;
stud1.nome[0]=J;

// OK

stud1.nome=Jim;

// ERRORE DI COMPILAZIONE

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

ESEMPIO MODIFICATO
struct studente{
int matricola;
char *nome;
char *cognome;
int num_esami;
int voti[30];

NB: ad una variabile di tipo


struct studente viene riservato
spazio per:
- 1 int (matricola)
- 1 indirizzo (nome)
- 1 indirizzo (cognome)
- 1 int (num_esami)
- 30 int (voti)

};
struct studente stud1;
stud1.nome=Jim;

// OK
// per non acquisibile via scanf
// e modifica con [] non ammessa!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

Nota su assegnamento di variabili struttura con campi vettore


struct studente{
int matricola;
char nome[30];
char cognome[30];
int num_esami;
int voti[30];
};

struct studente stud1, stud2;

stud1=stud2;

//copia di tutti gli elementi


//compresi elementi vettori!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

VETTORI E STRUTTURE (2)


Le strutture possono essere elementi di un vettore
ESEMPIO
struct studente{
int matricola;
char nome[30];
char cognome[30];
int num_esami;
int voti[30];
};
struct studente classe[20];

Prof. M. Giacomin

//vettore di 20 studenti!

Elementi di Informatica e Programmazione Universit di Brescia

18

ESEMPIO
Acquisizione da tastiera dei dati per tutti gli studenti della classe
(cfr lucido precedente)
for(i=0; i<20; i++){
printf(Studente n. %d\n, i);
printf(Inserisci nome: );
scanf(%s, classe[i].nome);
printf(Inserisci cognome: );
scanf(%s, classe[i].cognome);
printf(Inserisci matricola: );
scanf(%d, &(classe[i].matricola));
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

19

ESEMPIO (continua)
printf(Inserisci il numero di esami: );
scanf(%d, &(classe[i].num_esami));
for(j=0; j<classe[i].num_esami; j++){
printf(Inserisci voto esame n. %d, j);
scanf(%d, &((classe[i].voti)[j]) );
}
}

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

20

ESERCIZI ED ESEMPI DA TRATTARE DA SOLI


1) Modificare il codice precedente per lacquisizione della classe
di studenti sviluppando e utilizzando una funzione per
lacquisizione di uno studente passato in ingresso per indirizzo.
Il prototipo della funzione dovrebbe essere
void inputstudente(struct studente *s);

2) Potrebbe andare bene anche il seguente prototipo? Perch?


void inputstudente(struct studente s);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

21

3) Esaminare le seguenti quattro funzioni (e le corrispondenti chiamate)


per scambiare due elementi di un vettore. Solo due scambiano
effettivamente i due elementi del vettore del chimante: QUALI?
Esempio 1
void scambiaelem (int x, int y){
int temp;
temp=x;
x=y;
y=temp;
}
int v[5]={1,2,3,4,5};
scambiaelem(v[2], v[3]);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

22

Esempio 2
void scambiaelem (int v[], int ix, int iy){
int temp;
temp=v[ix];
v[ix]=v[iy];
v[iy]=temp;
}

int v[5]={1,2,3,4,5};
scambiaelem(v, 2, 3);

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

23

Esempio 3
struct vettstr{
int v[5];
};
void scambiaelem (struct vettstr v, int ix, int iy){
int temp;
temp=v.v[ix];
v.v[ix]=v.v[iy];
v.v[iy]=temp;
}

struct vettstr v={{1,2,3,4,5}};


scambiaelem(v, 2, 3);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

24

Esempio 4
struct vettstr{
int v[5];
};
void scambiaelem (struct vettstr *v, int ix, int iy){
int temp;
temp=v->v[ix];
v->v[ix]=v->v[iy];
v->v[iy]=temp;
}

struct vettstr v={{1,2,3,4,5}};


scambiaelem(&v, 2, 3);
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

25

SOLUZIONE
1: la funzione non scambia nulla, opera su compie locali di
v[2] e v[3] (nei parametri formali x e y)
2: la funzione scambia effettivamente gli elementi, perch opera
sul vettore del chiamante, passato per indirizzo
3: la funzione non scambia gli elementi del vettore (della struttura)
del chiamante, perch opera su una copia locale della struttura
4: la funzione scambia gli elementi del vettore (della struttura)
del chiamante, perch opera sulla struttura del chiamante
passata per indirizzo

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

26

ESEMPI DA ESAMINARE SUL LIBRO:


Conversione lettere minuscole/maiuscole (Fig. 7.10 pag. 255)
Visualizzazione stringa un carattere per volta (Fig. 7.11 pag. 256)
Copia di stringa in due versioni (Fig. 7.21 pag. 273)
tryToModifyArray (Fig. 6.14 pag. 207)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

27

Complementi di C
Qualificatore const
Ridefinizione di tipo

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

IL QUALIFICATORE CONST
Introdotto nella versione ANSI-C del linguaggio
Specifica che una variabile (eventualmente un parametro) non pu
essere modificata dal programma: assegnamenti risultano in errori
a tempo di compilazione
La qualifica const si riferisce specificamente a ci che si trova
alla sua destra (vedi esempi successivi)
Esempio 1
const float limitefebbre=36.6;

// Inizializzazione

limitefebbre=37;

// ERRORE!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 2 (puntatore variabile a dati costanti)


int a;
int b;
const int *intPtr = &a;

// const si riferisce all oggetto


// di tipo int!

a=10;
b=20;
intPtr = &b;

// OK

*intPtr = 20;

// ERRORE!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 3 (puntatore costante a dati variabili)


int a;
int b;
int * const intPtr = &a;

// const si riferisce al puntatore!

a=10;
b=20;
*intPtr = 20;

// OK, assegna 20 ad a

intPtr = &b;

// ERRORE!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 4 (puntatore costante a dati costanti)


int a;
int b;
const int * const intPtr = &a;

// const int + const intPtr

a=10;
b=20;
*intPtr = 20;

// ERRORE!

intPtr = &b;

// ERRORE!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ESEMPI NEL CONTESTO DELLE FUNZIONI


float arearettangolo(const struct rettangolo * const pr);
// da questo prototipo chiaro che il rettangolo non verr
// modificato dalla funzione e pr (copia locale) non sar
// modificato nella funzione (non si tratta di un array)

/* copia la stringa s2 nel vettore s1 */


copiastringa (char *s1, const char *s2);

//stringa s2
// non modificata

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

RIDEFINIZIONE DI TIPO
Un nuovo tipo pu essere definito uguale ad un altro tipo:
typedef <tipoesistente> <nomenuovotipo>
Esempio:
typedef int numeromaglia;
typedef float mediagoal;

e poi si possono dichiarare variabili come


numeromaglia magliaPazzini, magliaPato;
mediagoal mgPazzini, mgPato;

e usarle, per esempio


magliaPazzini = 11;
mgPato=0.35;
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 1 con struct


struct punto{
float

x;

float

y;

};
typedef struct punto Punto;

//Punto pu essere usato


//come nuovo tipo

Punto pt1, pt2;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 2 con struct (pi tipico)


typedef struct {
float

x;

float

y;

} Punto;

//Punto pu essere usato


//come nuovo tipo

Punto pt1, pt2;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Esempio 1 con enum


enum squadre{Milan, Juve, Inter};
typedef enum squadre Squadre;
Squadre sq1=Milan;

Esempio 2 con enum


typedef enum {Milan, Juve, Inter} Squadre;
Squadre sq1=Milan;

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

Linguaggio C
Algoritmi di ordinamento e ricerca

Universit degli Studi di Brescia


Prof. Massimiliano Giacomin

ORDINAMENTO DI VETTORI
Dato un vettore, es. int v[10]
0

9 5 2 3 2 10 2 10 4 1
permutare i suoi elementi in modo da ottenere un vettore ordinato,
ad esempio tale che v[0] v[1] v[2] v[3] v[9]
0

1 2 2 2 3 4 5 9 10 10
COME? Esistono diversi algoritmi standard, ne vediamo uno
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Bubble sort (o per scambi): idea di base (1)


0

9 5 2 3 2 10 2 10 4 1
0

5 9 2 3 2 10 2 10 4 1
0

5 2 9 3 2 10 2 10 4 1
0

5 2 3 9 2 10 2 10 4 1
Prof. M. Giacomin

- Per ogni coppia


v[i] v[i+1]:
se v[i]>v[i+1] allora
v[i] e v[i+1]
vengono scambiati
- PASSATA:
tutte le coppie
dalla prima
allultima

Elementi di Informatica e Programmazione Universit di Brescia

Bubble sort (o per scambi): idea di base (2)


0

5 2 3 2 9 10 2 10 4 1
0

5 2 3 2 9 10 2 10 4 1
0

5 2 3 2 9 2 10 10 4 1
0

5 2 3 2 9 2 10 10 4 1
Prof. M. Giacomin

- Per ogni coppia


v[i] v[i+1]:
se v[i]>v[i+1] allora
v[i] e v[i+1]
vengono scambiati
- PASSATA:
tutte le coppie
dalla prima
allultima

Elementi di Informatica e Programmazione Universit di Brescia

Bubble sort (o per scambi): idea di base (3)


0

5 2 3 2 9 2 10 4 10 1
0

5 2 3 2 9 2 10 4 1 10
DOPO UNA PASSATA, LELEMENTO
MASSIMO POSTO PIU A DESTRA
E FINITO IN ULTIMA POSIZIONE
(QUELLA CORRETTA)
Prof. M. Giacomin

- Per ogni coppia


v[i] v[i+1]:
se v[i]>v[i+1] allora
v[i] e v[i+1]
vengono scambiati
- PASSATA:
tutte le coppie
dalla prima
allultima

Elementi di Informatica e Programmazione Universit di Brescia

Bubble sort (o per scambi): idea di base (4)


0

9 5 2 3 2 10 2 10 4 1
PRIMA PASSATA da 0 a n-1 v[n-1] contiene MAX v[0..n-1]
0

5 2 3 2 9 2 10 4 1 10
SECONDA PASSATA da 0 a n-2 v[n-2] contiene MAX v[0..n-2]
0

2 3 2 5 2 9 4 1 10 10
TERZA PASSATA da 0 a n-3 v[n-3] contiene MAX v[0..n-3]
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

Bubble sort (o per scambi): idea di base (5)


ECC. ECC.
0

2 1 2 2 3 4 5 9 10 10
ULTIMA PASSATA da 0 a 1 v[1] contiene MAX v[0..1]
vettore v ORDINATO!
0

1 2 2 2 3 4 5 9 10 10

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ALGORITMO BUBBLE-SORT (pseudocodice)


for(i=n-1; i>=1; i--)

// i= n-1, n-2, , 1

< FAI UNA PASSATA DA 0 A i>

NB: vettore v di n elementi


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

ALGORITMO BUBBLE-SORT
for(i=n-1; i>=1; i--)
for(j=0; j<i; j++){

// i= n-1, n-2, , 1
// PASSATA DA 0 A i

if(v[j]>v[j+1]){
temp=v[j];
v[j]=v[j+1];
v[j+1]=temp;
}
}

NB: vettore v di n elementi


Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

MIGLIORAMENTO ALGORITMO
0

1 1 2 2 3 4 7 9 10 10
SE IL VETTORE RISULTA
GIA ORDINATO, NON SI
EFFETTUA NESSUNO SCAMBIO!
IDEA: effettuare la passata successiva solo se
ci sono stati scambi nella passata precedente!

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

10

for(i=n-1; i>=1; i--){

// i= n-1, n-2, , 1

fattoscambio=0;
for(j=0; j<i; j++){

// PASSATA DA 0 A i

if(v[j]>v[j+1]){
temp=v[j];
v[j]=v[j+1];
v[j+1]=temp;
fattoscambio=1;
}
}
if(!fattoscambio)
break;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

11

COMPLESSITA ALGORITMO (cenni)


Numero di scambi effettuati nel caso peggiore:
Passata 0..n-1:

n-1

Passata 0..n-2:

n-2

Passata 0..1:

Totale: 1 + 2 + + n-1
n!1
n(n !1)
= "i =
i=0
2
ovvero: O(n2)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

12

ALGORITMI DI ORDINAMENTO
IL PROBLEMA DELLORDINAMENTO
Ordinare un insieme di elementi, ciascuno dotato di chiave, in
modo che sia rispettata una relazione dordine tra le chiavi.
TABELLA ALGORITMI DI ORDINAMENTO
caso: migliore medio
Selection Sort
O(n2)
O(n2)
O(n2)

peggiore
O(n2)

STABILE

Bubble Sort

O(n)

O(n2)

STABILE

Quick Sort

O(nlog n) O(nlog n) O(n2)

STABILE

Heap Sort

O(nlog n) O(nlog n) O(nlog n) NON ST.

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

13

ALGORITMI DI RICERCA
IL PROBLEMA
Determinare se in un insieme di elementi, ciascuno dotato di chiave,
esiste un elemento dotato di chiave k.
DUE ALGORITMI FONDAMENTALI
Nessuna informazione sullinsieme:
RICERCA SEQUENZIALE
Insieme ordinato:
RICERCA BINARIA (migliore complessit)

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

14

RICERCA SEQUENZIALE
Si scorrono gli elementi del vettore dal primo allultimo
trovato=0;
for(i=0; i<n; i++)
if(v[i]==k){
trovato=1;
break;
}

// trovato indica se k presente, i contiene la posizione

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

15

RICERCA BINARIA
IPOTESI: il vettore ordinato
IDEA DI BASE (es: k=2)
0

1 2 2 3 5 6 6 7 10 10
inf

med

sup

Si cerca tra inf e sup (estremi inclusi: elementi da esaminare)


- se v[med]==k: TROVATO
- se v[med]<k:
si cerca tra med+1 e sup
(inf=med+1, med=(inf+sup)/2)
- se v[med]>k:
si cerca tra inf e med-1
(sup=med-1, med=(inf+sup)/2)
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

16

v[med] > k
0

1 2 2 3 5 6 6 7 10 10
inf med

sup

A questo punto v[med]==k


Fino a quando si va avanti in generale?
- finch inf sup:

k potrebbe essere in v[inf..sup]

- se inf >sup:

k non nel vettore

Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

17

RICERCA BINARIA
inf=0, sup=n-1, med=(inf+sup)/2;
trovato=0;
while(inf<=sup){
if(v[med]==k){
trovato=1;
break;
}
if(v[med]<k)
inf=med+1;
else sup=med-1;
med=(inf+sup)/2;
}
Prof. M. Giacomin

Elementi di Informatica e Programmazione Universit di Brescia

18

You might also like