Sottoprogrammi: procedure e funzioni - 1


Una subroutine è una parte separata di un programma che ha un nome e risolve il proprio compito separato. La subroutine si trova all'inizio del programma principale e può essere lanciata (chiamata) dal programma principale specificandone il nome.

L'utilizzo delle subroutine consente di evitare la duplicazione del codice se è necessario scrivere lo stesso codice in posti diversi programmi . 
Le librerie importate in un programma (ad esempio, System) sono costituite da routine che sono già state compilate da qualcuno. I programmatori non devono pensare a quali algoritmi sono implementati in essi, li applicano semplicemente, pensando solo a cosa stanno facendo esattamente. Questo è un grande risparmio di tempo. Non è necessario scrivere un algoritmo che è già stato scritto da qualcun altro.

Ogni subroutine dovrebbe eseguire solo un'attività, calcolare qualcosa o produrre alcuni dati o fare qualcos'altro. 

Le subroutine, o metodi, sono di due tipi:  funzioni (quelle che restituiscono il risultato del lavoro) e procedure (quelle che non lo fanno).

Iniziamo con il secondo tipo. Proviamo a scrivere un semplice esempio.
Supponiamo di dover visualizzare sullo schermo la stringa "Errore". ogni volta che può verificarsi un errore nel codice per colpa dell'utente (ad esempio, quando inserisce dati errati).
Questo può essere fatto scrivendo la dichiarazione
Console.WriteLine("Error");>
Ora immaginiamo che questa riga debba essere inserita in più punti del programma. Certo, puoi semplicemente scriverlo ovunque. Ma questa soluzione ha due inconvenienti.
1) questa stringa verrà memorizzata molte volte;
2) se vogliamo modificare l'output in caso di errore, dovremo modificare questa riga in tutto il programma, il che è piuttosto scomodo.

Per questi casi sono necessari metodi e procedure.
Un programma con una procedura potrebbe avere questo aspetto:

usando il sistema;
classProgram {
    static void PrintError() {
        Console.WriteLine("Errore");
    }
    static void Main() {
        PrintError();
    }
}

 

Una procedura inizia con la parola void. Dopo il nome della procedura vengono scritte parentesi vuote.
Tutte le istruzioni eseguite in una procedura sono rientrate. 
Il modificatore Static  indica che il campo, il metodo o la proprietà specificati non apparterranno a ciascun oggetto della classe, ma a tutti insieme.
I metodi e le procedure sono scritti prima del metodo principale Main().

Per fare riferimento a una procedura, nel programma principale devi chiamarla per nome e non dimenticare di scrivere le parentesi.
Puoi chiamare una procedura in un programma un numero qualsiasi di volte.

Ora immaginiamo di dover visualizzare messaggi diversi in risposta a un errore dell'utente, a seconda che esattamente quale errore ha commesso.
In questo caso, puoi scrivere la tua procedura per ogni errore: 

 

void printErrorZero() {     Console.WriteLine("Errore. Divisione per zero!"); }

 

 

void printErrorInput()
{
    Console.WriteLine("Errore nell'input!");
}

E se ci fossero molti più errori possibili? Allora questa soluzione non ci andrà bene.
Dobbiamo imparare a controllare la procedura dicendole quale messaggio di errore visualizzare.
Per fare ciò, abbiamo bisogno di parametri che scriveremo tra parentesi dopo il nome della procedura
void printError(string s)
{
    Console.WriteLine(s);
}
In questa procedura, s è un parametro, una variabile speciale che permette di controllare la procedura.
Il parametro è una variabile dal cui valore dipende il funzionamento della subroutine. I nomi dei parametri sono elencati separati da virgole nell'intestazione del sottoprogramma. Il tipo di parametro è scritto prima del parametro.

Ora, quando si chiama la procedura, è necessario specificare il valore effettivo tra parentesi che verrà assegnato al parametro (la variabile s) all'interno della nostra procedura
printError("Errore! Divisione per zero!");
Questo valore è chiamato argomento.
L'argomento è il valore del parametro che viene passato alla subroutine quando viene chiamata.
L'argomento può essere non solo un valore costante, ma anche una variabile o un'espressione aritmetica. /span>< /span>

Variabili locali e globali
Spesso è necessario utilizzare variabili aggiuntive che verranno utilizzate solo nella subroutine. Tali variabili sono chiamate locali (o locali) e possono essere manipolate solo all'interno della subroutine in cui vengono create.
 
L'ambito della variabile locale è il blocco tra parentesi graffe all'interno del quale è dichiarato.
Il programma principale in C# è anche una subroutine, quindi tutte le variabili dichiarate all'interno di void Main() sono variabili locali. Altre subroutine non "sanno" nulla delle variabili locali di altre subroutine.

Pertanto, è possibile limitare l'ambito (ambito) di una variabile solo alla subroutine in cui è realmente necessario. In programmazione, questa tecnica è chiamata incapsulamento  - nascondere la variabile per non modificarla dall'esterno.

Se è necessario dichiarare una variabile che sarebbe visibile in qualsiasi punto del programma (in qualsiasi subroutine), allora tali variabili vengono dichiarate al di fuori di tutte le subroutine (vedere il programma 3 dalla tabella sottostante).
Tali variabili sono chiamate global.

In C#, all'avvio del programma, tutte le variabili globali vengono automaticamente impostate a zero (le variabili booleane assumono il valore false).

Analizza tre programmi:
1) In questo programma, la variabile i è locale. Una variabile locale è dichiarata all'interno di una subroutine. 2) Qui, anche se c'è una variabile i nel programma principale (con valore 7), verrà creata una nuova variabile locale i con valore 5. 
Quando questo programma viene eseguito, il valore 75 apparirà sullo schermo.
3) Questo programma ha una variabile globale i. Il suo valore può essere modificato all'interno della subroutine e all'interno del programma principale.
La procedura funzionerà con la variabile globale i e le verrà assegnato un nuovo valore pari a 2. Viene visualizzato il valore 2.
test del vuoto statico() {   int io = 5; Console.Write("i"); } test del vuoto statico() {   int io = 5;   Console.Write("i"); } vuoto statico Main() { int io = 7;   Console.Write("i");   test(); } utilizzando il sistema; programma di classe { int io; test del vuoto statico() {   io = 2; } vuoto statico Main() { test(); Console.Write("i"); } }

Attività
Scrivi una procedura che scambia i valori di due variabili.

La particolarità di questo compito è che abbiamo bisogno che le modifiche apportate alla procedura diventino note al programma chiamante.

Proviamo a scrivere la procedura in questo modo: static void Swap (int a, int b) // con una tale descrizione dei parametri della procedura, { // copierà i valori degli argomenti (x e y) intero c; // le variabili a e b sono variabili indipendenti non correlate a x e y c = un; un = b; b=c; } vuoto statico Main() { int x=1, y=2; Scambia(x, y); //i valori delle variabili x e y (argomenti) vengono copiati nei parametri a e b, x = 1, y = 2 } Se esegui questo programma, puoi vedere che i valori delle variabili x e y non sono cambiati. Affinché i parametri modifichino i valori degli argomenti, è necessario utilizzare i dati che passano per riferimento. Per fare ciò, è necessario scrivere ref prima del nome del tipo di dati nell'intestazione del sottoprogramma. void Swap ( ref int a, ref int b ) // ora le variabili a e b ottengono gli indirizzi delle variabili x e y in memoria { intero c; c = un; un = b; b=c; } vuoto statico Main() {   int x=1, y=2;   Scambia(ref x, ref y); Applicazione: se passi un argomento per riferimento, solo il nome della variabile (NON un numero e NON un'espressione aritmetica) può stare in questo posto quando chiami la procedura.

Non puoi chiamare una procedura come questa:
Scambia(x, 4);
Scambia(5+x, y);