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:

  • La chiamata a sotto programma
    Avviene quando nel programma principale richiama una serie di istruzioni locate in altro punto della codifica per assolvere ad una funzione specifica del programma.
    All’atto della chiamata possono essere scambiati fra programma principale e sottoprogramma valori o variabili
  • Il tipo di chiamata a sotto programma
    • Non parametriche ovvero non vi è scambio dati diretto fra programma chiamante e sottoprogramma ma solo dati in comune fra tutte le unità di programma
    • Parametriche sono passati dati in valore o per variabile dal programma chiamante al sottoprogramma
  • Tipologia di dati utilizzati
    • Variabili e costanti globali visibili nel programma e nei sottoprogrammi in C si dichiarano dopo la direttiva #include
    • Variabili locali visibili solo nei sottoprogrammi ove sono dichiarati in C/ si dichiarano all’interno delle funzioni.
    • Parametri formali variabili e costanti simboliche utilizzate nei sottoprogrammi per la scrittura di codice che sia indipendente dal programma principale contesto;
    • Parametri attuali variabili e costanti globali che si sostituiscono all’atto della chiamata nel sottoprogramma ove sono utilizzati;
  • Tipologia di chiamate parametriche
    • Esiste la chiamata a sottoprogramma per indirizzo o referenza o riferimento quando viene passata una copia della variabile globale. In questo caso se nel sottoprogramma cambia la variabili globale la modifica si propaga nel programma principale
    • Nella chiamata per valore si passa il valore che in quel momento assume la variabile globale nel programma principale senza alterare quindi la variabile globale nel programma principale.

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.