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