User Tools

Site Tools


it:informatica:linguaggio_c:funzioni_1
Return to Home page

Funzioni (Esempio 1)

Concetti:
Funzione non complessa con passaggio dei parametri per valore

Testo:

  • Si scriva una funzione che riceve in ingresso due numeri di tipo float (a e b),

li moltiplica e restituisce il risultato della moltiplicazione.

  • Si applichi tale funzione ad un vettore di nome vet al fine di moltiplicare per 3

ogni suo elemento.

  • Il risultato della moltiplicazione dovrà essere salvato su un vettore ris di pari dimensione.

Soluzione:

funzioni_1.c
/* 
   Si scriva una funzione che riceve in ingresso due numeri di tipo float (a e b),
   li moltiplica e restituisce il risultato della moltiplicazione.
   Si applichi tale funzione ad un vettore di nome vet al fine di moltiplicare per 3
   ogni suo elemento.
   Il risultato della moltiplicazione dovrà essere salvato su un vettore ris di pari dimensione.
 */
 
 
#include <stdio.h>
#define SIZE 10
 
/* Prototipo */
float mul(float a, float b);
 
int main(){
 
  float vet[SIZE] = {1.0, 5.0, 3.0, 7.0, 10.0, 1.0, 2.0, 3.0, 4.0, 5.0};
  float ris[SIZE];
  int i;
 
  /* Moltiplicazione degli elementi di vet per 3 e salvataggio in ris */
  for(i=0; i < SIZE; i++){
    ris[i] = mul(vet[i], 3.0);
  }
 
  /* Stampa del risultato */
  for(i=0; i < SIZE-1; i++){
    printf("%f ", ris[i]);
  }
  printf("%f\n", ris[SIZE-1]);
 
  return 0;
}
 
 
/* Corpo della funzione: funzione mul, che esegue la moltiplicazione di due numeri (a e b). */
float mul(float a, float b){
  float risul;
 
  risul = a*b;
 
  return risul;
}
 
/* La funzione mul poteva essere scritta nel seguente modo */
/*
float mul(float a, float b){
    return a*b;
}
*/

Commenti:

  • Durante il processo di compilazione il compilatore deve conoscere i prototipi di tutte le funzioni utilizzate all'interno di un programma. Questo viene fatto o tramite la direttiva #include (che serve ad includere un file che contiene tra le varie cose i prototipi di alcune funzioni (ad esempio il file stdio.h contiene tra i vari prototipi anche quello delle funzioni scanf e printf) o scrivendo direttamente e prima del loro utilizzo i prototipi delle funzioni che verranno utilizzate in seguito. Nell'esempio specifico:
/* Prototipo */
float mul(float a, float b);

indica che in seguito verrà utilizzata una funzione di nome mul che ha come parametri di ingresso due variabili di tipo float e come valore restituito una variabile di tipo float. Il nome dei parametri non è importante nel processo di compilazione, quindi questa riga di codice potrebbe essere sostituita con la seguente:

/* Prototipo */
float mul(float, float);

Nota: Se si scrive il corpo della funzione prima del utilizzo della funzione, la dichiarazione del prototipo non è più necessaria (con il termine corpo si intende l'implementazione della funzione, cioè il codice che la realizza). Il compilatore infatti, analizzando il corpo della funzione, ha tutte le informazioni necessarie per capire il nome della funzione, i tipi e il numero di parametri e il tipo del valore restituito. Il compilatore utilizzerà questi dati per controllare che la funzione sia utilizzata nel seguito in modo corretto, in particolare se il numero di parametri e il tipo di parametri ad essa passati sono coerenti con il prototipo.

  • Analizzando il programma:
int main(){
 
  float vet[SIZE] = {1.0, 5.0, 3.0, 7.0, 10.0, 1.0, 2.0, 3.0, 4.0, 5.0};
  float ris[SIZE];
  int i;
 
  /* Moltiplicazione degli elementi di vet per 3 e salvataggio in ris */
  for(i=0; i < SIZE; i++){
    ris[i] = mul(vet[i], 3.0);
  }
 
  /* Stampa del risultato */
  for(i=0; i < SIZE-1; i++){
    printf("%f ", ris[i]);
  }
  printf("%f\n", ris[SIZE-1]);
 
  return 0;
}

dopo aver dichiarato ed inizializzato il vettore vet e dichiarato tutte le altre variabili, il primo ciclo for esegue la moltiplicazione di tutti gli elementi del vettore vet per 3.0, salvando i risultati nel vettore ris.

ris[i] = mul(vet[i], 3.0);

si noti che viene utilizzata la funzione mul, la quale moltiplica il primo parametro ris[i] per il secondo paramentro 3.0, ottenendo come risultato della moltiplicazione un numero di tipo float. La seguente linea di codice:

ris[i] = mul(vet[i], 1.0+2);

avrebbe fornito lo stesso risultato, così come anche la seguente riga di codice che non fa utilizzo della funzione mul:

ris[i] = vet[i]*3.0;

Il secondo ciclo for stampa invece il contenuto del vettore ris.

  • Il corpo della funzione, cioè il codice che implementa (realizza) la funzione è invece il seguente:
/* Corpo della funzione: funzione mul, che esegue la moltiplicazione di due numeri (a e b). */
float mul(float a, float b){
  float risul;

  risul = a*b;

  return risul;
}  

In pratica i valori passati alla funzione, cioè ris[i] e 3.0, vengono copiati rispettivamente nella variabili a e b. Si noti che tutte le variabili interne alla funzione (cioè a, b e risul) sono locali alla funzione. Infatti, ogni volta che viene eseguita la funzione, lo spazio sufficiente a salvare le 3 variabili viene allocato nella memoria del calcolatore. Tali variabili possono essere usate all'interno della funzione ma, alla fine della funzione, esse smettono di esistere e la memoria da loro precedentemente allocata viene resa libera per altre variabili. All'interno della funzione le variabili a e b hanno perciò valori ris[i] e 3.0 (si noti che la modifica del valore della variabile a NON comporta la modifica anche del valore della variabile ris[i]). All'interno della funzione viene dichiarata una variabile “locale” di nome risul. In risul viene salvato il risultato della moltiplicazione di a per b. Con il comando return il valore della variabile risul viene restituito al chiamante, cioè al programma principale che aveva chiamato la funzione mul(vet[i], 3.0). In pratica è come se a mul(vet[i], 3.0) venisse sostituito il risultato della moltiplicazione di vet[i] per 3.0. Si noti che il programma principale è scritto anch'esso dentro una funzione che si chiama int main(). Tale funzione riceve in ingresso nessun parametro (si sarebbe potuta scrivere anche come int main(void), dove il termine void indica un tipo nullo, cioè nessun parametro). Alla fine della funzione int main() c'è il comando return 0;. Tale comando indica di ritornare al chiamante il valore 0. Nel caso della funzione int main() il chiamante è il sistema operativo (Windows, Linux, Mac OS,…) e il valore 0 restituito al sistema operativo sta ad indicare che il programma è terminato correttamente (si noti infatti dal prototipo della funzione int main() che essa restituisce un numero di tipo int).

  • La funzione float mul(float a, float b) può essere scritta equivalentemente nel seguente modo:
float mul(float a, float b){
    return a*b;
}

in tal caso non si fa uso della variabile risul per salvare il risultato della moltiplicazione tra a e b, ma si restituisce immediatamente il risultato di tale operazione (return a*b;).


If you found any error, or if you want to partecipate to the editing of this wiki, please contact: admin [at] skenz.it

You can reuse, distribute or modify the content of this page, but you must cite in any document (or webpage) this url: https://www.skenz.it/it/informatica/linguaggio_c/funzioni_1
/web/htdocs/www.skenz.it/home/data/pages/it/informatica/linguaggio_c/funzioni_1.txt · Last modified: 2020/11/26 23:18 (external edit)