Linguaggio C – Lezione n.7 – I sotto programmi

L’argomento di questa lezione è la scomposizione di problemi in sotto problemi e la scrittura di sotto programmi in linguaggio C.
Una domanda importante quali sono le caratteristiche fondamentali della scomposizione del problema secondo la metodologia Top Down ?
Quando un problema è troppo complesso da risolvere in un unico algoritmo e quindi in un unico programma, si preferisce scomporre il problema in sotto problemi e risolvere in maniera separata ogni sotto problema. Tutti i sotto problemi derivando dal problema complesso si scambiano dati e tutti insieme concorrono alla soluzione complessiva.
I vantaggi di tale approccio sono:
Semplificazione del programma;
Riuso di codice riprodurre senza ripetere il codice nello stesso programma;
Portabilità riuso stesso codice in altri programmi
Queste tre caratteristiche da sole già bastano per giustificare tale approccio.
Ad ogni sotto problema corrisponde una soluzione che risolve una parte o una funzionalità del problema che si traduce in un sotto programma.
Un sotto programma è un’unità di codice autonoma che risolve una parte del problema.
In tutti i linguaggi di programmazione esistono i sotto programmi anche se sono definiti in modo diverso dal punto sintattico come è ovvio che sia.
Però alcuni concetti fondamentali sono ricorrenti e sono:

In tutti i linguaggi di programmazione si definiscono il concetto di procedura e funzione: una procedura è un sotto programma che esegue un compito o un’attività ma non ritorna valore al chiamante in modo diretto e viene dichiarata con parola chiave “void nome([elenco argomenti]) { codice C}, mentre una funzione ritorna obbligatoriamente un valore ed è dichiarata con la sintassi:
tipo nome ([elenco argomenti]) { Codice C return tipo valore; }
in questo caso {elenco argomenti} sono l’elenco dei parametri formali che sono facoltativi ma di fatto sono sempre utilizzati. La funzione ha un tipo di dato di ritorno che in modo generalizzato può essere un qualunque tipo anche astratto, ma per semplificare può essere un int, double, char, ecc.
L’istruzione return dovrà ritornare al chiamante la stessa tipologia di dato.
Vediamo un esempio di funzione con il codice anche del main

#include <stdio.h>
float n,r;
float cubo(float x ){
     float c=x*x*x;
return c} 
main()
    printf(“inserisci il numero di cui vuoi calcolare il cubo\t”);
scanf(“%f“,&n);
r=cubo(n);
     printf(“Il cubo è:\t %f”,r);
 return ;
}

Il codice si commenta da solo, è definita una funzione cubo che calcola il cubo di un numero e ritorna il risultato al chiamante. Il main riceve in input un numero da tastiera e invoca la funzione che memorizza all’atto della chiamata il valore nella variabile r. In questo codice x è un parametro formale, mentre n e r sono variabili globali in quanto dichiarate sotto la direttiva #include.
Un altro esempio è una procedura che è scritto nel codice sotto riportato.

#include <stdio.h>
 int a,b,s;
void somma (int x,int y , int *z)
{*z=x+y;}
main ()
{a=3;
 b=5;
somma(4,5,&s);
 printf("\n La somma è: %d",s);
return;
}

In questo programma le variabili a,b,s sono globali, x,y,z sono parametri formali e in particolare z è dichiarato come puntatore con la notazione “*” e alla chiamata a sotto programma viene richiamato nella chiamata con il simbolo della “&”. In questo caso l’area di memoria è condivisa fra il programma main e il sotto programma.
Questo per citare alcuni esempi ed ecco il video della lezione.