FUNZIONI La libreria standard del C fornisce una ricca collezione di funzioni, come le funzioni: double sqrt(double) double pow (double, double) della libreria matematica, che abbiamo già usato anche senza sapere come sono codificate. I programmi possono usare funzioni già codificate ma possono anche codificarne di nuove. Se scriviamo programmi ben strutturati e progettati con metodologia topdown possiamo individuare “componenti” piccole e maneggevoli” da codificare con funzioni appropriate. Le funzioni servono per codificare piccole componenti Esempio 1. Parametri formali non modificati dalla funzione #include <stdio.h> int mcd(int,int); /* prototipo */ int main() { int x , y; puts("Scrivi due interi positivi:"); scanf("%d%d", &x, &y); printf(“MCD(%d,%d) = %d.\n”, x,y, mcd(x,y)); /* chiamata */ /* usa parametri attuali */ return 0; } int mcd(int a, int b) /* definizione */ /* usa parametri formali */ { int x; if (a < b) { x=a;a=b;b=x;} x = b; while(a%x !=0 || b%x !=0) x--; return x; } 1 Il prototipo della funzione dichiara il suo uso nel file, i tipi degli argomenti che riceve ed il tipo del valore che ritorna. Una chiamata di funzione specifica il nome della funzione e gli argomenti (attuali) di cui la funzione chiamata necessita. L a definizione specifica il codice necessario per calcolare il valore della funzione a partire da argomenti formali. Una funzione ritorna un valore. La definizione è una sola, le chiamate possono essere multiple. Esempio 2. Parametro formale modificato dalla funzione #include <stdio.h> int fatt( int ); /* prototipo*/ int main() { int x; puts(“Dammi un intero non negativo:”); scanf(“%d”,&x); printf("Il fattoriale di %d e' %d\n", x, fatt(x)); /*chiamata*/ return 0; } int fatt( int n ) { int f; /*definizione*/ if (n <= 1) return 1; for(f = 1;n > 1;n--) f*=n; return f; } Esempio 3. Il mcd con l'algoritmo di Euclide che modifica i parametri int mcd(int a, int b) { int x, r; /* definizione alternativa */ if (a < b) { x=a;a=b;b=x;} r=a%b; while(r != 0){ a = b; b = r; r = a%b; } return b; } 2 Esempio 4. Array tra i parametri #include <stdio.h> int maxArray(int [], int); /* prototipo */ int main() { int a[7]= {12,23,14,25,66,199,2461}, lun; lun = 4; printf("Il massimo dei primi %d interi e' : %d.\n", lun, maxArray(a,lun)); /* chiamata*/ lun = 7; printf("Il massimo dei primi %d interi e' : %d.\n", lun, maxArray(a,lun)); /* chiamata*/ return 0; } /*ritorna il massimo dei primi n>=1 elementi dell’array a*/ int maxArray(int a[], int n) /* definizione */ { int i, max; for (max = a[0], i = 1; i < n ; i++) if(max < a[i]) max=a[i]; return max; } • Formato del prototipo : return-value-type function-name (parameter-type-list); Necessario quando la chiamata della funzione precede, nel programma, la definizione della funzione. Il tipo del valore restituito è int per default, è void se la funzione non restituisce niente. • Parametri attuali Sono le variabili passate dalla funzione chiamante alla funzione chiamata. • Formato della definizione: return-value-type function-name (parameter-list ) { declarations and statements } • Parametri formali Sono variabili (locali) che ricevono i valori dei corrispondenti parametri attuali della funzione chiamante. • Variabili locali Tutte le variabili dichiarate nella definizione di una funzione sono locali. Esse sono note solo alla funzione nella quale sono definite. 3 Passaggio parametri int main () int mcd ( int a, int b) { { int x, y; int x; // leggi x ed y ......mcd(x, y); } return x; } x a y b x int main () int fatt ( int n ) { { int f; int x; ….. // leggi x return 1; ......fatt(x); ….. return f; } } x n f N.B. I valori delle variabili della funzione chiamante non vengono mai alterati. 4 int main () int maxArray (int a[ ] , int n ) { { int a[7], lun; int i, max; // inizializza a[] //assegna un valore a lung return max; } .....maxArray(a, lun); } lun n a a i max N.B. Gli elementi dell'array a[] della funzione chiamante sono accessibili dalla funzione chiamata che quindi può alterarne i valori. Header Files Hanno suffisso .h e contengono prototipi di funzioni. Di sistema. Vengono inclusi con: #include <filename.h> come: #include <stdlib.h> #include <math.h> Di utente. Sono definiti dal programmatore e sono salvati con un nome a piacere come mio_header.h. Vengono poi inclusi con: #include “mio_header.h” 5 Passaggio di array bidimensionale #include <stdio.h> void quadraArrayBid(int [][4],int,int); void stampaArrayBid(int [][4],int,int); int main() { int i, mat[3][4]={ {1,2,3,4}, {5,6,7,8}, {9,8,7,6} }; quadraArrayBid(mat, 2, 2); stampaArrayBid(mat, 2, 2); return 0; } /*fa il quadrato di n*m elementi dell'array mat */ void quadraArrayBid(int mat[][4], int n, int m) { int i,j; for (i = 0;i < n; i++) for (j = 0;j < m; j++) mat[i][j] *= mat[i][j]; } /*stampa n*m elementi dell'array mat */ void stampaArrayBid(int mat[][4], int n, int m) { int i,j; for (i = 0;i < n; i++){ for (j = 0;j < m; j++) printf("%4d", mat[i][j]); puts(""); } } Stamperebbe: 1 4 25 36 6