Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Funzioni
Prototipo di una funzione.
Riproduzione dell’intestazione, seguita da ‘;’.
Sintatticamente analogo a una dichiarazione di
variabile;
scope: dalla dichiarazione a fine file;
i nomi dei parametri sono facoltativi;
dà visibilità alla funzione, anche prima della sua
definizione. Es.:
double power(int base, int expo);
void beeps(int n);
oppure
double power(int, int);
void beeps(int); Corso di Laboratorio di LinguaggiCorso A – p.28/57
Funzioni
double power(int base, int expo);
...
int main(void)
{ ...
p=power(a,k); /* Ok, qui power() e‘ nota ... */
...
}
Array
Array monodimensionali.
Sono variabili indicizzate, omogenee per tipo.
sintassi della dichiarazione:
T x[N ];
|{z}
dichiaratore
Esempio.
int x[5];
int a=0;
x[5]=3; // Fuori da x[] !!!
a=a+x[5]; // a=indefinito!
Corso di Laboratorio di LinguaggiCorso A – p.31/57
Array
L’operatore di assegnazione = non può essere utilizzato
tra array.
int x[10], y[10];
...
x=y; /* Errore! */
Una funzione non può ritornare array.
Es.: | {z } [4] ;
int x[3]
| {z }
Array
int x[3][4];
Esercizio. Dichiarando
double y[3][4][2];
come è memorizzato y?
che tipo hanno le espressioni y[1] e y[2][2]?
Array
y[1] è un (array di 4 (array di 2 double))
y[1][0][0], y[1][0][1],
y[1][1][0], y[1][1][1],
y[1] ⇐⇒
y[1][2][0], y[1][2][1],
y[1][3][0], y[1][3][1],
int x[];
double y[][10];
/* la seconda dim. e‘ obbligatoria! */
Array
Passaggio di parametri.
Nelle definizioni di funzione i parametri array si
dichiarano sempre con gli operatori [ ].
Il tipo può però essere incompleto: la prima dimensione
è opzionale, quelle successive sono obbligatorie.
La seguente funzione ritorna l’indice corrispondente al massimo elemento del vettore v[].
Si noti che la “lunghezza” n viene passata esplicitamente.
int pos_max(double v[], int n)
{
int i, res;
res=0;
for(i=1; i<n; i++)
if( v[res]<v[i] )
res=i;
return res;
}
Corso di Laboratorio di LinguaggiCorso A – p.38/57
Array
Nelle funzioni, i parametri di tipo array sono specificati
sempre con [ ] — il tipo può essere incompleto.
Il passaggio di un parametro array ha l’effetto di un
passaggio by reference.
La contraddizione con quanto detto in precedenza sul
passaggio by value è solo apparente.
Di fatto viene passato un puntatore by value.
Array
#define COLS 5
void somma_colonne(int x[][COLS], int sum[],
int Nr_rows)
{ int i, j;
for(j=0; j<COLS; j++) {
sum[j]=0;
for(i=0; i<Nr_rows; i++)
sum[j]+=x[i][j];
}
...
int m[3][COLS]= { {1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15} };
int s[COLS];
somma_colonne(m, s, 3);
// in uscita s=(18,21,24,27,30) Corso di Laboratorio di LinguaggiCorso A – p.40/57
Array
Valori iniziali.
La dichiarazione di un array unidimensionale con valori
iniziali ha la struttura
Array
L’inizializzazione completa un array con tipo incompleto.
int main(void)
{ int i, j;
for(i=0; i<ROWS; i++) {
for(j=0; j<COLS; j++)
printf( "\t%g", m[i][j] );
printf( "\n" );
}
printf("\n");
for(i=0; i<ROWS; i++)
printf( "%d\n", pos_max(m[i],COLS) );
return 0;
}
Corso di Laboratorio di LinguaggiCorso A – p.43/57
Stringhe
Stringhe di testo e caratteri.
Il linguaggio C fornisce un supporto minimo per la
gestione di stringhe.
Il tipo char garantisce, in ogni implementazione, di
poter rappresentare i codici numerici dei caratteri
stampabili (es. ASCII 0–127).
Le stringhe sono memorizzabili come array di char.
Convenzionalmente, un array di char che rappresenta
una stringa ha come ultimo elemento il carattere ’\0’.
Il carattere ’\0’ è il terminatore di stringa.
Si comporta a tutti gli effetti come la costante
numerica 0.
char nome[]="Pippo";
Stringhe
Il C non offre altri tipi di supporto nativi per i dati di tipo
stringa.
Operatori come il concatenamento, l’assegnazione o il
confronto di stringhe non fanno parte del linguaggio.
char s1[]="Pippo, s2[]="Pluto", s3[20];
printf( s1+s2 ); // Sbagliato
if( s1<s2 ) ... // Sbagliato
s3=s1; // Sbagliato
#include <string.h>
T *p;
Puntatori
Assegnazione e dereferenziazione.
L’operatore &hvariabilei ritorna l’indirizzo della variabile
argomento.
Se p è un’espressione di tipo T * che punta a una
variabile x di tipo T ,
l’espressione *p è equivalente a x.
Puntatori
Passaggio di parametri per riferimento.
In C il passaggio per riferimento non esiste.
Le variabili di tipo puntatore permettono di gestire in
modo esplicito il passaggio di riferimenti.
Se una funzione func deve modificare un parametro a,
deve ricevere il suo indirizzo (e trattarlo di
conseguenza).
void func(int *a) // dimezza il valore di a
{
*a /=2;
}
...
int x=5;
func(&x); // x=2
Corso di Laboratorio di LinguaggiCorso A – p.50/57
Puntatori
Puntatori e vettori.
Se p, x sono un puntatore e un vettore dichiarati come
T x[N ];
T *p;
k è un’espressione intera 0 ≤ k ≤ N − 1 e
p punta a x[0],
Puntatori
Puntatori e vettori.
Ogni variabile di tipo T [] (“vettore di T ”), nella
valutazione delle espressioni, viene convertita in un
puntatore a T .
T x[N ];
T *p;
T [] e T *
sono sinonimi.
Quindi il passaggio dei vettori che avviene “per
riferimento” non è un’eccezione, ma è conforme alle
regole di valutazione delle espressioni in C e alla
“semantica” dei puntatori.
Puntatori
La seguente versione di pos_max è equivalente a quella
già data.
int pos_max(double *v, int n)
{
int i, res;
res=0;
for(i=1; i<n; i++)
if( v[res]<v[i] )
res=i;
return res;
}
typedef T DX ; /* (1) */
X var;
T Dvar ;
si sostituisce var a X in DX .
/* Questo vett[10] e‘ un
dichiaratore di array. */
typedef int vett[10]; Corso di Laboratorio di LinguaggiCorso A – p.56/57