Le funzioni di input/output - Università degli Studi di Parma

Transcript

Le funzioni di input/output - Università degli Studi di Parma
Dipartimento di Ingegneria dell’Informazione
Università degli Studi di Parma
Le funzioni di input/output
Fondamenti di Informatica
Laurea in
Ingegneria Civile e Ingegneria per l’ambiente e il territorio
<stdio.h>
Linguaggio C: Le basi
Stefano Cagnoni e Monica Mordonini
Input / Output
n
n
Input / Output
Il linguaggio C consente di definire funzioni aggiuntive
raggruppabili eventualmente in librerie .
Esiste in particolare una libreria standard s( tandard library) di
funzioni ; per rendere disponibili tali funzioni , occorre inserire nelle
dichiarazioni
globali
del
programma, la
direttiva
di
precompilazione:
#include <stdio.h >
n
La libreria standard comprende, tra le altre, le seguenti funzioni
di input/output
Il linguaggio C
printf (<stringa di formato > [,<lista di espressioni> ])
n
n
n
per visualizzare dati sullo standard output
<lista di espressioni > ::= <espressione> {, <espressione>}
q sono espressioni il cui valore deve essere visualizzato
<stringa di formato >: contiene caratteri da visualizzare ed i
simboli di formato per i valori delle espressioni da visualizzare :
q %d
per la visualizzazione di un numero intero
q %f
per la visualizzazione di un numero reale
q %c
per la visualizzazione di un carattere
q %s
per la visualizzazione di una stringa
3
Esempi
Il linguaggio C
Input / Output
printf (“Questa è una frase di prova \n”);
scanf
(< stringa
variabili> )
printf ( “La somma di %d e %d risulta: %d\n”,
m, n, m+n);
printf
(“Il
codice
ASCII
visualizzato come %c \n”,61,61)
5
> ,< lista
indirizzi
n
Esempio
Ma
Il linguaggio C
formato
n
%d\nviene
Il codice ASCII 61viene visualizzato come A
di
consente la lettura di dati dallo standard input
<lista di indirizzi di variabili> ::= <indirizzo> {,<indirizzo>}
<indirizzo> : : = &<variabile>
<stringa di formato>
n
n
q
4
scanf (“%d %f %c ”, &n, &x, &c);
scanf (“%s”, nomestringa);
Il linguaggio C
6
1
Esempio
n
Esempio
Programma che legge due numeri e ne visualizza la somma
n
#include <stdio.h>
int main(){
int m, n;
printf (“Inserire primo numero:”);
scanf (“%d”, &m);
printf (“Inserire secondo numero:”);
scanf (“%d”, &n);
printf (“La somma di %d e %d risulta
%d\n”, m, n, m+n);
return 0;
Legge un codice ASCII e ne visualizza il carattere
#include <stdio.h>
int main(){
char c;
printf (“Inserire il codice ASCII:”);
scanf (“%d”, &c);
printf (“Il carattere corr. è %c\n”, c);
return 0;
}
}
Il linguaggio C
7
Il linguaggio C
8
Strutture di controllo
Strutture di controllo
n
Selezione if
if (< condizione> ) < istruzioni> [else < istruzioni> ]
< istruzioni > ::= <istruzione> | ‘{‘ < istruzione> {< istruzione> } ’}’
A esempio
if (x > 0)
If, while, for, ...
falso ↔ 0
vero ↔ non 0
operatori di confronto
maggiore >
maggiore o uguale >=
minore <
operatori logici minore o uguale <=
not!
uguale ==
and&&
diverso !=
or| |
y = x;
else
y = -x;
printf(“dato %d\n”, y);
Il linguaggio C
Esempio
10
Strutture di controllo
n
/* Dati due numeri in ingresso , individua il maggiore* /
#include <stdio.h>
#include <conio.h>
int main(){
int num1,num2;
Ciclo for
for(< istr .iniziale> ;< condizione> ;< istr . ciclica> )< istr .>
A esempio: calcolo della somma dei primi 100 numeri naturali
#include <stdio.h>
int main(){
int i, somma = 0;
clrscr()
printf("Immetti i due numeri:");
scanf("%d%d",&num1,&num2);
if (num1==num2) printf("I due numeri sono uguali");
else
if(num1>num2)printf("Il primo è maggiore”);
else printf("Il secondo è maggiore");
return 0 ;
for ( i=1; i<=100; i=i+1)
somma = somma+i;
printf (“La somma vale: %d \n”, somma);
return 0;
}
}
Il linguaggio C
11
Il linguaggio C
12
2
Strutture di controllo
Operatori di incremento e decremento
Ciclo while
n
while (< condizione> )
n
< istruzioni>
A esempio: calcolo radice quadrata intera ( cioè la parte intera) di un
numero intero n
#include <stdio.h>
int main(){
int n, radice = 1;
radice=radice−1
printf (“Inserire il numero:”);
può essere scritto
scanf (“%d” , &n);
radice− −
while (radice*radice <= n)
oppure
− −radice
radice++;
radice−−;
printf (“La radice vale %d\ n”, radice);
n
++ e -Esempi
q
y=x++
il contenuto della variabile x viene inizialmente usata per
l’assegnazione y, e solo dopo incrementata
q
y=--x
il contenuto della variabile x viene inizialmente incrementato
di uno e solo dopo viene effettuata l’assegnazione di x a y
return 0;}
Il linguaggio C
13
Strutture di controllo
n
Il linguaggio C
Strutture di controllo
n
Ciclo do
do < istruzioni> while (< condizione> )
Esempio trovare un programma che legge e addiziona dei numeri ,
terminaquando la somma supera il valore 1000
#include < stdio.h>
int main(){
int i, somma = 0, cont = 0;
do{
printf ( “Inserire nuovo numero :” );
scanf (“ %d ”, &i);
somma = somma + i;
cont++;
}while (somma < = 1000);
printf ( “I numeri letti sono % d\ n” ,cont);
return 0;
}
Il linguaggio C
Selezione switch
< istr. switch>::=switch(<espr.> )‘{‘<istr. case> |< istr. default> ’}’
< istr.case >::=case< valore intero> :{case < valore intero> :} < istr.> [break]
< istr. default>::= default < istr.>
2
A L egg e due numeri ed un simbolo di operazione (+,−,∗ ,/); visualizza il
risultato dell’operazione richiesta
#include < stdio.h>
int main(){
int m,n;
char operazione,invio;
printf (“ Inserire i due numeri: ”) ;
scanf ( “%d%d” , &m,&n);
printf ( “Inserire l’ operazione :” );
scanf ( “%c%c” , &invio , &operazione) ;
15
Strutture di controllo
switch ( operazione ) {
case ‘+ ’:
printf(“ Risultato %d \n ”,
break;
case ‘− ’:
printf(“ Risultato %d \n ”,
break;
case ‘∗ ’:
printf(“ Risultato %d \n ”,
break;
case ‘/ ’:
printf(“ Risultato %d \n ”,
break;
default:
printf(“ operazione
14
Il linguaggio C
16
Esempio
/* Legge la data d i nascita di una persona nel formato giorno/mese/anno e la data
attuale nello stesso formato; calcola poi l'et à della persona in anni */
#include < stdio.h>
int main(){
int g_att,m_att,a_att,g_nas,m_nas,a_nas;
m+ n);
m− n);
printf("immetti la data di nascità : ");
scanf("%d%d%d",&g_nas,&m_nas,&a_nas) ;
printf("immetti la data attuale: ");
scanf("%d%d%d",&g_att,&m_att,&a_att) ;
if ( m_att> m_nas || m_att= =m_nas && g_att> =g_nas )
printf("l'et à (in anni ) è : %d",a_att- a_nas) ;
else
printf("l'et à (in anni ) è : %d",a_att- a_nas- 1);
return 0;
m∗ n);
m/ n);
non consentita\ n” );
}
}
return 0;}
Il linguaggio C
17
Il linguaggio C
18
3
Strutture di dati
Una struttura di dati ha le seguenti propriet à:
n
è un insieme di dati
Strutture dati
q
n
Es. una struttura contenente il totale delle vendite
un’azienda in ognuno dei dodici mesi di un anno
effettuate da
ogni dato dell’insieme può essere singolarmente identificato rispetto
agli altri
q
Es. si deve poter conoscere il totalevenduto in un certo mese
n
la modalità d i identificazione dei singoli dati, consente che una
stessa istruzione, eseguita in momenti diversi, possa operare su
diversi dati della struttura
n
possono esistere operazioni che agiscono a livello dell’ intera
struttura
Vettori e matrici
q
Es. deve essere possibile leggere, con un ciclo, tutte le fatture (emesse
da un’ azienda, contenute in un archivio)
Il linguaggio C
Vettori
Vettori
n
n
n
n
20
un vettore (array unidimensionale ) è un insieme di elementi
dello stesso tipo
ha un nome che lo identifica
gli elementi del vettore vengono identificati , oltre che con il
nome del vettore di appartenenza, con il valore di un indice
numerico
giorni_mese
1
31
28
2
31
0
indice
n
nome vettore
per identificare un elemento si utilizza il nome del vettore seguito
dal valore dell’indice racchiuso tra parentesi.
es. giorni_mese [3]
il valore dell’indice può essere una qualsiasi espressione; ad
esempio
es. giorni_mese [n+3]
n
occorre dichiarare il tipo degli elementi e la dimensione del vettore
(in C i vettori hanno dimensione prefissata)
<tipo> <nome > ‘[‘ <dimensione> ‘]’
n
il valore dell’indice parte da zero
un vettore occupa locazioni contigue di memoria
n
n
il C non effettua alcun controllo (n é in fase di compilazione, né in
fase di esecuzione) sul superamento dei limiti di un vettore
contenuto
Il linguaggio C
21
Vettori
Il linguaggio C
22
Array Multidimensionale
/* Programma che legge n numeri in un vettore e li visualizza in ordine
inverso */
#include < stdio.h>
#define MAX 100
int main (){
int n, i, numeri[MAX ] ;
/* Lettura dimensione vettore */
printf ( “Inserire il numero di elementi: ”) ;
scanf (“ %d ”, &n);
if (n> MAX) printf ( “Valore troppo elevato \n ”) ;
else{
/* lettura dei numeri */
for (i= 0; i< n; i++){
printf ( “Inserire un numero: ”) ;
scanf (“ %d ”, & numeri[i ]);
}
/* visualizzazione dei numeri in ordine inverso */
for(i= n− 1; i> = 0; i− − ) printf (“ %d \n ”, numeri[i]);
}
return 0;}
Il linguaggio C
n
hanno due o più indici (o dimensioni)
n
in C, occorre dichiarare la dimensione di ogni indice
<tipo> <nome> ‘[‘<dimensione>‘]’ { ‘[‘<dimensione>‘]’ }
n
23
i vettori bidimensionali sono denominati matrici
Il linguaggio C
24
4
Esempio
/*legge, per righe, gli elementi di una matrice 2× 3 e stampa la somma d i ogni riga*/
#include < stdio.h>
#define N_RIGHE 2
#define N_COLONNE 3
int main(){
int i, j, somma , numeri[N_RIGHE][N_COLONNE] ;
for (i= 0; i< N_RIGHE; i+ + )
{
printf (“ Inserisci riga n.%d\ n” , i+ 1);
for (j= 0; j< N_COLONNE; j+ + ) {
printf (“ Inserisci elemento n.%d: ”, j+ 1);
scanf (“ %d ”, & numeri[i][j]);
}
}
for (i= 0; i< N_RIGHE; i+ + )
{
somma= 0;
for (j= 0; j< N_COLONNE; j+ + )
somma+ = numeri[i][j ];
printf (“ La somma della riga n.%d vale %d \n ”, i+ 1, somma );
}
Caratteri e stringhe
<string.h>
return 0;}
Il linguaggio C
25
Caratteri e Stringhe
Caratteri e stringhe
Lettura di un carattere da tastiera (dispositivo standard di
input):
getchar()
n
accetta caratteri fino alla pressione del tasto invio;
solo allora restituisce il primo carattere inserito; gli altri restano
in memoria.
n
Esempi
char c;
c=getchar();
putchar(c)
Scrittura di un carattere sullo schermo (dispositivo standard di
output)
n
putchar (<espressione carattere>)
Il linguaggio C
27
Stringa
Il linguaggio C
28
Lettura di una stringa da tastiera
n
È una sequenza di caratteri
n
In C non esiste il dato di tipo stringa; una stringa viene
memorizzata in un array di caratteri
gets (<array>)
char nome[30]
n
Il C usa la tecnica di contrassegnare la fine effettiva di una
stringa con il carattere avente codice 0 ( ‘\0’)
n
Inizializzazione di una stringa:
char nome[30]=”Luca ” (inserisce automaticamente
il carattere ‘\0’)
Il linguaggio C
29
//termina l ’immissione con il tasto
“invio”
scanf (“%s”, <array>) //termina l ’immissione con il
tasto “invio ” (il codice del
tasto invio non viene letto)
n
in entrambi i casi, l’inserimento di un numero di
caratteri maggiore della lunghezza dell’array, ha
effetti imprevedibili
Il linguaggio C
30
5
Esempio
Scrittura di una stringa su schermo
//legge una stringa e conta le eventuali cifre presenti al suo
interno
#include < stdio.h>
#define MAX_CAR 128
int main() {
int i, n_cifre= 0;
char stringa [MAX_CAR];
puts (“Inserire una stringa: ”);
gets (stringa);
for (i= 0; i< MAX_CAR; i+ + ) {
if (stringa[i]= = ’\0’) break;
if (stringa[i]> = ’0’ && stringa[i]< = ’9’)
n_cifre+ + ;
}
printf (“Il numero di cifre è %d\n”, n_cifre);
return 0;
}
puts (<espressione stringa>) //aggiunge ‘\n’
printf (“%s ”, <espressione stringa>)
Es. put s (stringa );
printf (“%s %s\n”, stri1, stri2);
Il linguaggio C
31
n
Per il loro utilizzo occorre includere il file string.h
strcpy (s1, s2)
copia la stringa s2 in s1
strcat (s1, s2)
concatena s2 alla fine di s1
strlen (s)
restituisce la lunghezza della stringa s
strcmp (s1, s2)
32
Funzioni di manipolazione delle stringhe
Funzioni di manipolazione delle
stringhe
n
Il linguaggio C
Copia due nomi in due stringhe , ne fa la
comparazione , stampa a video la più grande
(in ordine alfabetico) e unisce i due nomi in
una terza stringa e restituisce il numero di
caratteri del primo e del seconod numero
inserito.
confronta s1 con s2
Il linguaggio C
33
#include <stdio.h>
#include <string.h>
#define MAX_CAR 128
#define MAX_NOME 10
int main() {
int l;
char nome1[MAX_NOME], nome2[MAX_NOME2], mixed [MAX_CAR];
char titolo[30];
strcpy(nome1, “Topolino” );
strcpy(nome2, “Pluto”);
strcpy (titolo, “Questo e’ il titolo. ”);
printf (“%s \n\n”, titolo);
printf(“Il primo nome e’ %s \n”, nome1);
printf (“Il secondo nome e’ %s \n”, nome2);
if (strcmp(nome1, nome2) >0) /*comparazione alfabetica, la piu’ grande e’
pluto* /
strcpy(mixed, nome1);
else
Il linguaggio C
34
strcpy(mixed, nome2);
printf (“Il piu’ grande nome in ordine alfabetico e’ %s \n”, mixed);
/*utilizzo funzione strcat*/
strcpy ( mixed, nome1);
strcat(mixed, “ “);
strcat(mixed, nome2);
printf (“Entrambi i nom i sono %s \n”, mixed);
/*utilizzo funzione strlen* /
l=strlen(nome1);
printf (“Il primo nome e’ composto da %d caratteri\n”, l);
l=strlen(nome2);
printf (“Il secondo nome e’ composto da %d caratteri\n”, l);
return 0;
}
6
n
n
n
n
n
n
n
Questo e’ il titolo
Topolino
Pluto
Pluto (primo nome in ordine alfabetico)
Entrambi i nomi sono Topolino Pluto
Il primo nome e’ composto da 8 caratteri
Il secondo nome e’ composto da 5
caratteri
Le funzioni
Funzioni
Funzioni
n
Con il termine funzione si intende, in generale, un operatore
che, applicato a certi operandi, consente di calcolare un
risultato
n
Il linguaggio C consente la definizione di funzioni
n
Occorre dichiarare il cosiddetto prototipo della funzione nella
sezione delle dichiarazioni globali:
Esempi:
n
int somma (int m, int n);
int somma (int, int);
int fun (void);
Occorre definire la funzione
<tipo risultato> <nome funzione> ([<elenco par. >]){
<corpo della funzione>
}
<tipo risultato > <nome funzione > (<elenco
parametri >);
n
All’interno del corpo della funzione, si utilizza un’apposita
istruzione per uscire dalla funzione e restituirne il risultato:
return <espressione risultato>
dove:
<elenco parametri>
::= < tipo parametro>
[<nome
parametro> ] {,< tipo parametro> [<nome parametro >]}
Il linguaggio C
39
Esempio
Il linguaggio C
40
Funzioni con parametri
#include <stdio.h>
int leggi_numero (void);
int max ( int m, i n t n);
int main () {
int a, b,massimo;
a = leggi_numero();
b = leggi_numero();
massimo = max(a,b);
printf (“ Il massimo è %d\ n”,massimo);
return 0;
}
int leggi_numero(void) {
int n;
printf (“ Inserire un numero:”);
scanf (“% d”, &n);
return n;
}
int max (i n t m, int n) {
if (m>n) return m;
else return n;
}
Il linguaggio C
n
n
n
41
Possono operare su dati diversi per ogni
funzione
il programma che chiama la funzione deve
dichiarare nella chiamata i dati su cui
operare
Si dice che I parametri vengono passati per
valore
Il linguaggio C
42
7
Passaggio parametri per valore (by value)
n
n
ã
o
Esempio
Parametri formali utilizzati nella funzione chiamata
Parametri effettivi passati per valore dalla funzione
chiamante
I valori dei dati effettivi sono copiati nei parametri
formali utilizzati dalla funzione chiamata
Nessun effetto provocato da modifiche nel parametro
formale all’interno della funzione si ripercuote sul
parametro reale del programma chiamante
Il linguaggio C
n
n
Si realizzi un programma che legga da
tastiera il costo di listino di un prodotto e la
percentuale di sconto e visualizzi il prezzo da
pagare
si può realizzare una funzione che riceva
come parametri i due valori e calcoli il prezzo
finale
43
Esempio
Il linguaggio C
44
Esempio
/*Funzione con parametri*/
#include<stdio.h >
/*Definizioni generali - variabili globali*/
long int costo;
int percentuale;
long int prezzo_scont(long int valore, int percent)
{/*Definizioni interne alla funzione*/
long int val_scont;
/*Corpo della funzione*/
val_scont=valore-(valore*percent/100);
return (val_scont )}
void main()
{printf(“Introduci costo e percentuale (interi): \n”);
scanf(“%ld%d”,&costo,&percentuale);
printf(“Prezzo di listino: %ld, sconto: %d%%”, costo, percentuale);
printf(“prezzo finale: %dld\n”, prezzo_scont(costo, percentuale));}
Il linguaggio C
n
n
45
Funzioni : il passaggio di array
n
Gli array non sono passati per valore
n
Gli array vengono passati per indirizzo (in realtà si tratta
ugualmente di un passaggio per valore, in quanto in C il nome
di un array è l’indirizzo del primo elemento)
n
Se la funzione modifica il contenuto dell ’array, tale modifica si
riflette sull ’array originario
n
Non occorre specificare la dimensione dell ’array nell ’elenco
dei parametri formali
Il linguaggio C
Parametri formali: valore e percent
Parametri effettivi: costo e percentuale
Il linguaggio C
46
Esempio
/* Restituisce il valore del minimo di un vettore di interi. vet: vettore di
cui si cerca il minimo dim: numero di elementi del vettore */
#include <stdio.h >
int min_ele (int vet[], int dim );
int main(){
int i,numeri[10];
for (i= 0; i< 10; i++){
printf (“Inserire un numero:” );
scanf (“%d”, &numeri[i]);
}
printf(“Il minore e’ : %d”,min_ele(numeri,i );
return 0;}
int min_ele (int vet[], int dim ) {
int i, min;
min= vet[0];
for (i= 1;i< dim;i+ + )
if (vet[i]< min) min= vet[i];
return min;
}
47
8
Passaggio dei parametri by reference
Funzioni: passaggio per
riferimento
n
n
Cosa succede se la funzione deve restituire
più di un dato alla funzione chiamante?
Si passa l’indirizzo della cella di memoria in
cui è contenuto il risultato
La funzione swap e il passaggio di array
Il linguaggio C
Esempio di puntatore
Esempio di funzione che deve
ritornare più valori
#include<stdio.h>
int main(){
int dato; /* definizione di intero */
int *indirizzo_dato; /* definizione di puntatore ad un intero */
indirizzo_dato=&dato;/* assegna l’indir. di dato al puntatore */
dato=5; /* assegna un valore intero */
printf(“Il dato vale %d \n ”,dato); /*stampera’ il numero 5 */
*ind_dato=3; /* ora il dato vale 3 */
printf(“Il dato vale %d \n ”,dato); /*stampera’ il numero 3 */
return 0;
}
Il linguaggio C
#include <stdio.h>
void calcola (float valore, float *quad_val, float *cub_val) {
*quad_val =valore * valore;
*cub_val=*quad_val * valore;
return;
}
int main() {
float un_dato, quadrato, cubo;
printf(“Introduci una dato”);
scanf(“%f”, &un_dato);
calcola (un_dato, &quadrato, &cubo);
printf(“Il quadrato di %f e\’ : %f \n”,un_dato, quadrato);
printf(“Il cubo di %f e\’ : %f \n”,un_dato, cubo);
return 0;
}
50
n
Calcolare il quadrato e il cubo di un dato in
una sola funzione
51
Il linguaggio C
52
Osservazione
n
n
Importante la sintassi, si rischia di effettuare
errori che il compilatore non trova
Attenzione agli effetti collaterali: occorre
valutare che le variazioni introdotte nelle
procedure non abbiano ripercussioni
indesiderate in altre parti del programma
Il linguaggio C
54
9
#include <stdio.h>
void scambia(int *x, int *y) {
int z;
z = *x; *x = *y; *y = z;
return;}
void swap (int x, int y){
int z;
z=a; a=b; b=z;
}
int main() {
int a=3,
int b=5;
Esempio: provare la funzione swap (funzione
che commuta il valore fra a e b)
void swap (int a, int b) //a e b passatiper valore
{int t;
t=a; a=b; b=t;
}
NON SI HA ALCUN EFFETTO
printf ("Prima dello scambio swap: a=%d, b=%d. \n", a, b); /*a=3 e b=5*/
scambia(&a, &b);
printf ("Dopo lo scambio: a=%d, b=%d. \n", a, b); /*a=3 e b=5*/
void swap (int *a, int *b)//a e b ora sono dei puntatori
{ in t;
t=*a; *a=*b; *b=t;
}
chiamando swap(&x,&y) si OTTIENE lo scambio desiderato
Il linguaggio C
printf("Prima dello scambio scambia: a=%d, b=%d. \n", a, b); /*a=3 e b=5*/
scambia(&a, &b);
printf ("Dopo lo scambio: a=%d, b=%d. \n", a, b); /*a=5 e b=3*/
return 0; }
55
#include<stdio.h >
void prova(int a[], int b, int n)
void prova1(int a, int *b);
int main() {
int c[3], d;
c[0]=100; c[1]=15;c[2]=20; d=0;
printf(“Prima : %d,%d,%d,%d\n”, c[0], c[1], c[2], d);
prova(c,d,3);
printf(“Dopo prova : %d,%d,%d,%d\n”, c[0], c[1], c[2], d);
prova1(c[0], &d);
printf(“Dopo prova1 : %d,%d,%d,%d \n”, c[0], c[1], c[2], d);
return 0;}
void prova(int a[], int b, int n) //a per riferimento b n per valore
{int i;
for (i=1; i<n; i++) { a[i]=b; }
b =a[0];
return;}
void prova1(int a, int *b){
*b=a;
return;}
Prima: 100, 15,20, 0
Dopo prova : 100, 0,0,0
Dopo prova1: 100, 0,0,100
Esempio di
- passaggio per valore
-passaggio per reference
-passaggio di un array
-passaggio di una casella di array
Il linguaggio C
57
Strutture
Le strutture
n
Una struttura è un raggruppamento di variabili sotto un unico
nome; le singole variabili si chiamano membri della struttura:
* ESEMPIO
persona:
cognome
nome
indirizzo
data_nascita
n
indirizzo :
via
località
provincia
CAP
data_nascita:
giorno
mese
anno
Una struttura può contenere al suo interno ulteriori sottostrutture
Il linguaggio C
60
10
Strutture
Strutture
La definizione di una struttura in C avviene nel modo seguente:
n
n
struct < nome struttura> ‘{‘
<dichiarazione di variabile>
{ < dichiarazione di variabile> }
‘}’;
struct < nome struttura> < nome variabile> {,< nome variabile> };
* ESEMPIO
* ESEMPIO
struct data_nascita{
int giorno;
int mese;
int anno;
};
equivalentemente:
struct data_nascita {
int giorno, mese, anno;
};
Il linguaggio C
equivalentemente:
struct data_generica {
int giorno;
int mese;
int anno;
}data_fattura, data_bolla;
struct data_generica data_fattura, data_bolla;
Il linguaggio C
62
Esempio
Per fare riferimento ai membri di una struttura , se ne
qualifica il nome facendolo precedere dal nome della
variabile di struttura di appartenenza, inserendo un punto di
separazione
n
scanf(“%d%d%d”,&data_bolla.giorno,
&data_bolla.mese, &data_bolla.anno);
n
struct data_generica{
int giorno;
int mese;
int anno;
};
61
Strutture
n
La definizione di una struttura non definisce alcuna variabile, ma
solo un tipo di dato; per dichiarare variabili di tipo struttura:
Scrivere un programma che memorizzi una
agenda telefonica (massimo 10 componenti),
utilizzando una struttura persona.
È consentito ’l assegnamento diretto tra due variabili di
struttura dello stesso tipo; ad esempio:
data_fattura=data_bolla;
Il linguaggio C
#include <stdio.h>
#include <string.h>
#define MAXNOMI 10
#define MAXLUNG 20
struct persona{
char cognome[MAXLUNG];
char nome[MAXLUNG];
char telefono[MAXLUNG];
};
int main(){
struct persona agenda[MAXNOMI];
int n_tot_persone=i=0;
printf(“Introdurre il numero totale delle persone da introdurre
(<=10)\n”);
scanf(“%d”,& n_tot_persone);
if (n_tot_persone>10 || n_tot_persone<1)
printf (“Si deve introdurre un numero compreso fra 1 e 10\n”);
63
Il linguaggio C
64
else {
while(i< n_tot_persone) {
printf (“Introdurre il cognome della persona n. %d”, i);
scanf(“%s”, agenda[i].cognome);
printf(“Introdurre il nome della persona n. %d”, i);
scanf(“%s”, agenda[i].nome);
printf(“Introdurre il telefono della persona n. %d”, i);
scanf (“%s”, agenda[i].telefono);
i=i+1;
}
/*ciclo per la visualiz. dell’agenda*/
for(i=0; i<n_tot_persone,i++)
printf (“%s %s %s ”, agenda[i].cognome, agenda[i].nome,
agenda[i].telefono);
return 0;
}
}
11
I File
I File
n
n
normalmente con la parola file (o archivio) si intende un
insieme di informazioni, memorizzate su disco magnetico
le operazioni tipiche che si possono eseguire su di un file
sono:
q lettura di dati in memoria
q scrittura (aggiornamento o aggiunta) di dati dalla memoria
file
memoria
lettura
scrittura
Il linguaggio C
I File
n
n
n
I File
un file è una struttura dinamica, in quanto è possibile aggiungere
dei nuovi dati al suo interno, incrementando cos ì la sua
dimensione
per il C, un file non è altro che una sequenza di byte
esistono due tipi di file in C
q
q
Es. tastiera, monitor, stampante , file su disco, porta seriale …
q
esistono in particolare tre file standard utilizzabili direttamente da parte
di un qualunque programma C:
n
sono strutturati in linee di testo (tipicamente in codice ASCII )
stdin (standard input): è il dispositivo standard di input dei dati, normalmente
rappresentato dal terminale; viene usato dalle funzioni scanf(), getchar (),
gets(), …
stdout (standard output): è il dispositivo standard di output dei dati,
normalmente rappresentato dal monitor del terminale; viene usato dalle
funzioni printf(), putchar (), puts(), …
stderr (standard error ): è il dispositivo standard di visualizzazione dei
messaggi di errore, normalmente rappresentato dal monitor del terminale
q
n
il C identifica la fine di una linea, con il carattere ‘\n’
n
l’effettivo contenuto del file su disco, dipende dal modo in cui il sistema
operativo consente di realizzare i file di testo
q
file binari
n
i byte che vengono letti e scritti, corrispondono all’effettivo contenuto del file:
non viene effettuata alcuna conversione
n
anche un file di testo p u ò essere elaborato come file binario: in tal caso si
opera sull’effettivo contenuto in byte del file
Il linguaggio C
q
69
I File
n
più in generale, il C considera file, un qualunque dispositivo di I/O da
cui possono essere letti o su cui possono essere scritti dei byte di
informazioni
n
file di testo
n
Il linguaggio C
n
n
70
I File
quando si desidera elaborare un file, occorre dichiarare un
puntatore ad una struttura di dati apposita, di nome FILE e
definita nel file stdio.h
n
la prima operazione che deve essere effettuata su di un file è
la sua apertura
FILE* fopen(char* nomefile, char* modalit à);
Es. FILE* mio_file;
n
68
la struttura serve per memorizzare informazioni interne
indispensabili per l’elaborazione successiva del file stesso; chi
scrive il programma non è tenuto a conoscerne l’effettivo
contenuto
il puntatore serve, all’i nterno del programma , per fare
riferimento al file interessato, nelle successive operazioni
tale struttura non deve essere dichiarata per i tre file standard
Il linguaggio C
71
q
q
nomefile rappresenta il nome effettivo del file
modalità specifica il modo in cui il file verrà aperto; condiziona
le successive operazioni sul file stesso
n
la funzione fopen() crea una struttura di dati di tipo FILE,
restituisce come risultato il puntatore a tale struttura; in caso
di errore (file inesistente, ... ) restituisce null
n
i tre file standard , vengono aperti automaticamente
Il linguaggio C
72
12
I File
“r”
“w”
“a”
“r+”
“w+”
“a+”
I File
apre un file di testo esistente consente operazioni di lettura
si posiziona all’inizio del file
crea un nuovo file di testo consente operazioni di scrittura (aggiunta di linee
alla fine del file)
apre un file di testo esistente si posiziona alla fine del file consente operazioni
di scrittura (aggiunta di linee alla fine del file)
apre un file di testo esistente consente operazioni di lettura e di scrittura (in un
qualunque punto, con sovrascrittura dei byte preesistenti) si posiziona all’inizio
del file
crea un nuovo file di testo consente operazioni di lettura e di scrittura
apre un file di testo esistente si posiziona alla fine del file consente operazioni
di scrittura
n
Alla fine delle elaborazioni
l’operazione di chiusura
di un file, occorre effettuare
int fclose (FILE* puntatore )
q
q
q
q
libera la struttura di dati abbinata al file
in caso di scritture, garantisce che tutti i dati scritti sul file, siano
effettivamente trasferiti su disco
ritorna 0 se conclusa correttamente
comunque, alla terminazione di un programma C, il programma
stesso provvede a chiudere tutti gli eventuali file ancora aperti
(ma non ne garantisce la corretta scrittura)
Inserendo la lettera “ b” si ottengono le analoghe modalità per i file binari
Il linguaggio C
73
File di Testo
n
Il linguaggio C
Esempio
per leggere un carattere da un file di testo, si utilizza la
funzione:
/* legge i caratteri presenti in un file di testo e li invia al monitor */
#include < stdio.h>
int main(){
char c,nome[100];
FILE* f;
printf ( “Specificare i l nome del file: ”) ;
equivale a:
scanf (“ %s ”, & nome );
f=fopen(nome, “r”);
if ((f= fopen(nome , “r ”)) = = NULL)
if(f == NULL)
printf (“ Errore apertura file \n ”) ;
…
else{
while((c= fgetc(f ))!= EOF)
putchar (c);
equivale a:
fclose(f );
c=fgetc (f);
}
while(c!= NULL) {
return 0;
putchar (c);
c=fgetc (f);
}
int fgetc (FILE* puntatore)
q
q
q
q
74
legge un carattere dal file ed avanza sul carattere successivo
restituisce il carattere letto sotto forma di numero int (con i bit
oltre il primo byte, tutti uguali a zero)
restituisce il carattere ‘\n’ quando viene incontrata la fine di
una riga; restituisce ‘\n’ quando è effettivamente incontrato nel
file
restituisce un valore apposito, rappresentato dalla costante
E O F (definita in stdio.h, solitamente con il valore -1), per
indicare che si è raggiunta la fine del file
}
Il linguaggio C
75
File di Testo
n
Il linguaggio C
Esempio
per scrivere un carattere in un file (di testo o binario), si utilizza
la funzione:
/*aggiunge u n a r i g a alla fine di un file di testo, leggendo i caratteri d a tastiera*/
#include < stdio.h>
int main(){
char c,nome[100];
int fputc(int carattere , FILE* puntatore);
q
scrive un carattere nella posizione corrente del file
q
ritorna il carattere scritto, in caso di successo, EOF in caso di
errore
qualora si scriva il carattere di codice ‘\n’ in un file di testo, si ha
l’effetto di chiudere la linea corrente del file
q
76
FILE* f;
printf (“Specificare il nome del file:”);
scanf (“%s”, &nome);
getchar(); /* elimina ‘\n’ dal buffer della tastiera */
if ((f=fopen(nome, “a”)) == NULL)
printf (“Errore apertura file\n”);
else{
do{
c=getchar();
fputc(c, f);
}while (c!= ’\n’);
fclose(f );
}
return 0;
}
Il linguaggio C
77
Il linguaggio C
78
13
File di Testo
n
Esempio
Per leggere una stringa da un file (di testo o binario),
avanzando del numero di caratteri corrispondente, si utilizza la
funzione:
char* fgets(char* stringa,int lunghezza,FILE* puntatore);
q
occorre specificare la stringa destinata a contenere i caratteri letti ed il
numero massimo di caratteri che possono essereletti (compresi i caratteri
‘\n’ e ‘ \0’)
q
alla fine della stringa letta, viene memorizzato anche il carattere ‘\n’, oltre
al carattere di fine stringa‘\0’
q
la funzione termina quando viene letto il carattere ‘ \n’ (effettivo o
convertito) oppurequando viene esaurita la lunghezza specificata
q
ritorna NULL in caso di fine file o in caso di errore; ( ritorna il puntatore alla
stringafornita come parametro, in caso di successo)
Il linguaggio C
80
/* leggedelle stringhe e l e scrive in un file di testo nuovo; termina quando viene inserita una riga vuota */
#include < stdio.h>
#include < string.h>
int main() {
char nome[100], r i g a[100];
FILE* f;
p r i n t f (“ Specificare il nome d e l f i l e :”);
int fputs(const char * stringa,FILE* puntatore);
q
Il linguaggio C
Esempio
per scrivere una stringa in un file (di testo o binario),
si utilizza la funzione:
q
Il carattere ‘\n’ è già
presente nella stringa letta
79
File di Testo
n
/*legge le righe di un file di testo e le visualizza*/
#include < stdio.h>
int main() {
char nome[100],riga[100];
FILE *f;
printf ( “Specificare i l nome del file: ”) ;
scanf (“ %s ”, & nome );
getchar(); /* elimina ‘\ n’ dal buffer della tastiera */
if ((f= fopen(nome , “r ”)) = = NULL)
printf ( “Errore apertura file\ n” );
else{
while (fgets(riga,100,f)!= NULL)
printf(“ %s ”,riga );
fclose(f) ;
}
return 0;}
non aggiunge automaticamente il carattere ‘\n’ alla fine della
linea
ritorna EOF in caso di errore
scanf (“% s”, &nome );
getchar(); /* elimina ‘\n’ d a lbuffer della tastiera * /
i f ( ( f= fopen(nome, “w” )) = = NULL)
printf (“ Errore apertura f i l e\n ”);
else {
do {
gets(riga) ;
if (riga[0]!= ’\0’ ) {
strcat(riga, “\ n”) ;
fputs(riga,f );
}
}while (riga[0]!=’ \0’ );
fclose(f);
}
return 0;}
Il linguaggio C
81
n
Sono le analoghe di printf e scanf solo che va
specificato il file su cui scrivere o leggere
Esempi
q
q
82
/* Legge due temperature in gradi Celsius da un file, li converte in gradi Fahrenheit e li salva sul secondo file*/
fscanf e fprintf
n
Il linguaggio C
fscanf(miofile, “%d”,&intero);
fprintf(miofile, “%d\n”,intero);
Il linguaggio C
#include < stdio.h >
int main() {
float c1, c2, f1, f2;
char nomein [20], nomeout [20];
FILE* filein, fileout ;
printf (“Specificare il nome del file di input:”);
scanf (“%s”, &nome);
getchar(); /* elimina ‘\n’ dal buffer della tastiera */
if (( filein= fopen(nomein, “r”)) = = NULL)
printf (“Errore apertura file di input\n”);
else {
printf (“Specificare il nome del file di output:”);
scanf (“%s”, &nomeout);
getchar (); /* elimina ‘\n’ dal buffer della tastiera */
if ((fileout= fopen(nomeout, “w”)) == NULL)
printf (“Errore apertura file di output\n”);
else {
fscanf(filein , "%d", &c1);
fscanf(filein, "%d", &c2);
fprintf(fileout, "%d ", f1); /*mettiamo esplicitamente lo spazio di separazione */
f1=32+c1*9/5;
f2=32+c2*9/5;
fprintf(fileout, "%d", f2); /* fra il 1 e 2 numero con uno spazio dopo il %d */
fclose(fileout );
}
fclose(filein);
}
return 0;}
83
14
Ordinamento bubble sort
L’Ordinamento di vettori
Ordinare il vettore 5, 3, 7, 4, 10
Ciclo di scambi
(1- ciclo )
(2 - ciclo)
(3 - ciclo)
n
n
l’algoritmo bubble sort
5, 3, 7, 4, 10
3, 5, 7, 4, 10 J
3, 5, 7, 4, 10
3, 5, 4, 7, 10
3, 5, 4, 7, 10
3, 4, 5, 7, 10 J
3, 4, 5, 7, 10
3, 4, 5, 7, 10
3, 4, 5, 7, 10
3, 5, 4, 7, 10 J
3, 4, 5, 7, 10
3, 4, 5, 7, 10
3, 5, 4, 7, 10
3, 4, 5, 7, 10
3, 4, 5, 7, 10
2 scambi
1 scambi
3e4
4e5
86
void leggi(int v[])
{int i;
printf(“fornire la lunghezza del vettore < %d\n”,MAX);
scanf(“%d”,&size);
for (i=0;i<size;i=i+1)
{printf(“elemento di posto %d valore?\n”, i);
scanf(“%f”,&v[i]); printf(“valore %f\n”, v[i]);}
}
void scrivi(int v[])
{int i;
for (i=0;i<size;i=i+1)
printf(“elemento di posto %d e valore\n”, i, v[i]);
}
87
Ordinamento bubble sort
Il linguaggio C
88
Puntatori
n
void bubblesort(int v[], int iniz, int fine)
{int nonscambio, i;
float temp;
do{
nonscambio=true;
for (i=iniz; i<fine;i=i+1)
{if (v[i]>v[i+1]
{nonscambio=false;
temp=v[i]; v[i]=v[i+1]; v[i+1]=temp;
}
}
}
while(!nonscambio)
}
Il linguaggio C
2e3
Ordinamento bubble sort
#define MAX 5
#define true 1
#define false 0
int size; //dimensione corrente del vettore
void bubblesort(int v[], int inz, int fine);
void leggi(int v[]);
void scrivi(int v[]);
main()
{float vett[MAX];
printf (“ ordinamento di un vettore”);
leggi(vett);
bubblesort(vett,0, size -1);
scrivi(vett);}
Il linguaggio C
1e2
0 scambi
Il linguaggio C
Ordinamento bubble sort
partenza
n
n
n
n
89
L’indirizzo di un dato presente in memoria prende anche il nome
di puntatore a quel dato
è possibile memorizzare i puntatori all’interno di opportune
variabili (variabili puntatore )
quando si dichiara una variabile puntatore, si deve specificare il
tipo del dato a cui essa punta; ad esempio:
int *p
l’operatore & applicato al nome di un dato, restituisce l’indiri zzo
di quel dato
p = &i;
l’operatore * applicato ad un puntatore, consente di fare
riferimento al dato puntato, il valore che si assegna ad un
puntatore per indicare che esso non punta a nessun dato è
rappresentato dalla costante NULL (definita in stdio.h)
Il linguaggio C
90
15
Allocazione Dinamica della Memoria
Esempio
Legge due numeri e visualizza il maggiore dei due
#include <stdio.h>
main () {
int m,n,*maggiore;
printf (“Inserire due numeri: “);
scanf (“%d %d”,&m, &n);
if (m>n) maggiore = &m;
else maggiore = &n;
printf (“Il maggiore vale %d \n”, *maggiore );
}
n
Il linguaggio C
n
q
q
n
91
q
n
n
malloc: alloca un blocco di memoria contigua; richiede la
dimensione in byte
calloc: alloca un blocco di memoria contigua; richiede il
n
numero di elementi e la loro dimensione
q
q
q
q
n
Il linguaggio C
94
Esempio
la dimensione dei singoli elementi dipende in
genere dalla macchina; per rendere i
programmi portabili, il C mette a disposizione
la funzione:
size_t sizeof ( <variabile >| <tipo >)
essa restituisce come risultato la dimensione
in byte della variabile o del tipo di dato
specificato
printf (“%d%d”,sizeof(x),sizeof(double));
Il linguaggio C
num è il numero di elementi da allocare
dim è la dimensione in byte di ciascun elemento
size_t è un tipo definito in stdlib.h, per motivi di portabilità
dei programmi; può assumere valori interi ed è solitamente
dichiarato
93
Allocazione dinamica della Memoria
n
92
la funzione dello standard ANSI solitamente
richiamata per allocare memoria destinata ad un
array, è:
void *calloc(size_t num, size_t dim);
essa restituisce come risultato un puntatore a void
(per cui può essere assegnata ad un puntatore di
qualsiasi tipo); in caso di errore ritorna NULL
q
realloc: modifica la dimensione di un blocco di memoria
allocato in precedenza
free: libera la memoria di un blocco precedentemente
allocato
Il linguaggio C
Il linguaggio C
Allocazione dinamica della Memoria
la zona di memoria destinata all’allocazione
dinamica è denominata memoria heap
le funzioni standard per la gestione della memoria
dinamica sono dichiarate nel file stdlib.h
q
la dimensione della memoria necessaria è nota solamente
al momento dell’esecuzione
si vuole riutilizzare la stessa memoria per scopi diversi
la memoria allocata dinamicamente può essere
rilasciata, rendendola disponibile per eventuali
ulteriori allocazioni dinamiche durante l’esecuzione
del programma; alla terminazione del programma la
memoria dinamica viene comunque rilasciata
n
Allocazione dinamica della Memoria
n
un programma C può richiedere memoria
direttamente durante la sua esecuzione (allocazione
dinamica), nei punti in cui ciò si rende necessario
l’allocazione dinamica è particolarmente utile
quando:
n
/* Legge n numeri interi e li visualizza in ordine inverso; la quantità n viene
richiesta al momento dell’esecuzione */
#include <stdio.h>
#include <stdlib.h>
main(){
int *p,n,i;
printf(“Inserire il numero di elementi:”);
scanf(“ %d”, &n) ;
p = calloc(n, sizeof(int));
if (p == NULL) printf(“memoria insufficiente\n”);
else{
for(i=0; i<n; i++) {
printf (“Inserire un numero:”);
scanf (“%d”, &p[i]);
}
for(i=n- 1; i>=0; i--) printf (“%d\n”, p[i]);
}
}
95
Il linguaggio C
96
16
Programmazione Ricorsiva
n
Programmazione Ricorsiva
Molti linguaggi di programmazione consentono ad
un programma di chiamare direttamente o
indirettamente se stesso (chiamata ricorsiva)
Chiamata diretta
Chiamata indiretta
Programma P
….
Esegui P
…..
Programma P
….
Esegui Q
…..
Programma Q
…
Esegui P
….
Il linguaggio C
n
Esempio: funzione per il calcolo del fattoriale di un
numero
int fattoriale (int n) {
i f (n <= 1) return 1;
else return n fattoriale(n-1);
}
n
97
la ricorsione è resa possibile dal fatto che ogni
qualvolta una funzione viene richiamata, viene
creato nello stack, un nuovo ambiente locale alla
particolare attivazione della funzione stessa
Il linguaggio C
98
Stack
n
lo stack (pila) è una regione di memoria :
q
q
q
q
q
in cui è possibile aggiungere o eliminare dei dati (memoria
dinamica)
presenta una dimensione massima prefissata
l’ultimo dato inserito è il primo ad essere eliminato (LIFO)
viene gestita automaticamente dal programma, ed in particolare
al suo interno vengono memorizzati:
n
n
n
l’indirizzo di ritorno per le funzioni, al momento della loro chiamata
(vengono estratti al momento del ritorno al chiamante)
le variabili locali, in corrispondenza della loro dichiarazione (vengono
eliminate all’uscita dal loro ambiente di visibilità)
i parametri delle funzioni, al momento della loro chiamata (vengono
eliminati quando si ritorna al chiamante)
Il linguaggio C
99
17