Funzioni nella programmazione C con esempi: ricorsivo e inline

โšก Riepilogo intelligente

Nel linguaggio di programmazione C, le funzioni sono blocchi di codice riutilizzabili che suddividono un programma di grandi dimensioni in sottoprogrammi piรน piccoli, rendendolo piรน facile da comprendere, testare e modificare. Ogni funzione รจ composta da una dichiarazione, una definizione e una chiamata.

  • ๐Ÿงฉ Quali funzioni svolgono? Una funzione raggruppa le istruzioni riutilizzabili, in modo che un programma di grandi dimensioni venga suddiviso in sottoprogrammi piรน piccoli e gestibili, piรน facili da sottoporre a debug.
  • ๐Ÿ“š Due tipi: Le funzioni di libreria come printf e scanf sono giร  pronte all'uso, mentre le funzioni definite dall'utente vengono scritte dal programmatore.
  • ๐Ÿ“ Tre parti: L'utilizzo di una funzione implica la sua dichiarazione o prototipo, la sua definizione o corpo e la chiamata che la esegue.
  • ๐ŸŽฏ Argomenti: I valori vengono passati per posizione e, per impostazione predefinita, per valore, quindi la variabile originale rimane invariata all'interno della funzione chiamata.
  • ๐ŸŒ Scopo: Le variabili locali esistono solo all'interno della loro funzione, mentre le variabili globali e statiche mantengono i loro valori in tutto il programma o tra le chiamate.
  • ๐Ÿค– Assistenza AI: GitHub Copilot e gli assistenti basati sull'intelligenza artificiale generano automaticamente funzioni C, suggeriscono i tipi di ritorno e segnalano i valori di ritorno mancanti o gli argomenti non corrispondenti.

Funzioni nella programmazione in C

Cos'รจ una funzione in C?

Funzione nella programmazione in C Una funzione รจ un blocco di codice riutilizzabile che rende un programma piรน facile da comprendere, testare e modificare senza dover cambiare il programma chiamante. Le funzioni dividono il codice e modularizzano il programma per ottenere risultati migliori ed efficaci. In breve, un programma piรน grande viene suddiviso in vari sottoprogrammi chiamati funzioni.

Cos'รจ una funzione in C

Quando si divide un programma di grandi dimensioni in varie funzioni, diventa facile gestire ciascuna funzione individualmente. Ogni volta che si verifica un errore nel programma, puoi facilmente indagare sulle funzioni difettose e correggere solo quegli errori. รˆ possibile richiamare e utilizzare facilmente le funzioni ogni volta che sono necessarie, il che porta automaticamente a risparmiare tempo e spazio.

Biblioteca contro Funzioni definite dall'utente

Ogni programma 'C' ha almeno una funzione che รจ la funzione principale, ma un programma puรฒ avere un numero qualsiasi di funzioni. La funzione main () in C รจ il punto di partenza di un programma.

Nella programmazione 'C' le funzioni si dividono in due tipologie:

  1. Funzioni di libreria
  2. Funzioni definite dall'utente

La differenza tra la libreria e le funzioni definite dall'utente in C รจ che non รจ necessario scrivere un codice per una funzione di libreria. รˆ giร  presente all'interno del file header che inseriamo sempre all'inizio di un programma. Devi solo digitare il nome di una funzione e usarlo insieme alla sintassi corretta. Printf, scanf sono esempi di funzioni di libreria.

Considerando che una funzione definita dall'utente รจ un tipo di funzione in cui dobbiamo scrivere il corpo di una funzione e chiamare la funzione ogni volta che richiediamo che la funzione esegua qualche operazione nel nostro programma.

Una funzione definita dall'utente in C รจ sempre scritta dall'utente, ma in seguito puรฒ essere parte della libreria 'C'. รˆ un vantaggio importante della programmazione 'C'.

Le funzioni di programmazione C sono divise in tre attivitร  come,

  1. Dichiarazione di funzione
  2. Definizione della funzione
  3. Chiamata di funzione

Dichiarazione di funzione

La dichiarazione di una funzione consiste nello specificare il nome di una funzione all'interno di un programma. รˆ un passaggio obbligatorio per poter utilizzare le funzioni nel codice. In una dichiarazione di funzione, specifichiamo semplicemente il nome della funzione che useremo nel nostro programma, proprio come avviene per la dichiarazione di una variabile. Non possiamo utilizzare una funzione se non รจ dichiarata nel programma. La dichiarazione di una funzione รจ anche chiamata "prototipo di funzione".

Le dichiarazioni di funzione (chiamate prototipo) vengono solitamente eseguite sopra la funzione main() e assumono la forma generale:

return_data_type function_name (data_type arguments);
  • Il parametro return_data_type: indica il tipo di dati della funzione valore restituita all'istruzione chiamante.
  • Il nome della funzione รจ seguito da parentesi
  • I nomi degli argomenti, con le relative dichiarazioni di tipo di dati (facoltativamente), vengono inseriti tra parentesi.

Consideriamo il seguente programma che mostra come dichiarare una funzione cubo per calcolare il valore cubo di una variabile intera

#include <stdio.h>
/*Function declaration*/
int add(int a,b);
/*End of Function declaration*/
int main() {

Tieni presente che una funzione non restituisce necessariamente un valore. In questo caso viene utilizzata la parola chiave void.

Ad esempio, la dichiarazione della funzione output_message indica che la funzione non restituisce un valore: void output_message();

Definizione della funzione

La definizione di funzione significa semplicemente scrivere il corpo di una funzione. Il corpo di una funzione รจ costituito da istruzioni che eseguiranno un compito specifico. Il corpo di una funzione รจ costituito da una singola o da un blocco di istruzioni. รˆ anche una parte obbligatoria di una funzione.

int add(int a,int b)	//function body	
{
	int c;
	c=a+b;
	return c;
}

Chiamata di funzione

Una chiamata di funzione significa chiamare una funzione ogni volta che รจ richiesta in un programma. Ogni volta che chiamiamo una funzione, questa esegue un'operazione per la quale รจ stata progettata. Una chiamata di funzione รจ una parte opzionale di un programma.

  result = add(4,5);

Ecco il codice completo:

#include <stdio.h>
int add(int a, int b);	//function declaration
int main()
{
	int a=10,b=20;
	int c=add(10,20); 	//function call
	printf("Addition:%d\n",c);
	getch();
}
int add(int a,int b)	//function body
{
	int c;
	c=a+b;
	return c;
}

Produzione:

Addition:30

Argomenti della funzione

Gli argomenti di una funzione vengono utilizzati per ricevere i valori necessari dalla chiamata di funzione. Sono abbinati per posizione; il primo argomento viene passato al primo parametro, il secondo al secondo parametro e cosรฌ via.

Per impostazione predefinita, gli argomenti vengono passati per valore, ovvero una copia dei dati viene fornita alla funzione chiamata. La variabile effettivamente passata non cambierร .

Consideriamo il seguente programma che dimostra i parametri passati per valore:

int add (int x, int y); 
int main() {
  int a, b, result;
  a = 5;
  b = 10;
  result = add(a, b);
  printf("%d + %d\ = %d\n", a, b, result);
return 0;}
int add (int x, int y) { 
x += y;
  return(x);}

L'output del programma รจ:

5 + 10 = 15

Tieni presente che i valori di a e b passati alla funzione di aggiunta non sono stati modificati perchรฉ solo il suo valore รจ stato passato nel parametro x.

Ambito variabile

Per ambito variabile si intende la visibilitร  delle variabili all'interno di un codice del programma.

In C, le variabili dichiarate all'interno di una funzione sono locali a quel blocco di codice e non possono essere referenziate dall'esterno della funzione. Tuttavia, le variabili dichiarate al di fuori di tutte le funzioni sono globali e accessibili dall'intero programma. Le costanti dichiarate con #define all'inizio di un programma sono accessibili dall'intero programma. Consideriamo il seguente programma che stampa il valore della variabile globale sia dalla funzione main che da una funzione definita dall'utente:

#include <stdio.h>
int global = 1348;
void test();
int main() {
  printf("from the main function : global =%d \n", global);
  test () ;
return 0;}

void test (){
printf("from user defined function : global =%d \n", global);}

Risultato:

from the main function : global =1348
from user defined function : global =1348

Discutiamo i dettagli del programma:

Ambito variabile

  1. Dichiariamo una variabile globale intera con 1348 come valore iniziale.
  2. Dichiariamo e definiamo una funzione test() che non accetta argomenti nรฉ restituisce un valore. Questa funzione stampa solo il valore della variabile globale per dimostrare che รจ possibile accedere alle variabili globali ovunque nel programma.
  3. Stampiamo la variabile globale all'interno della funzione principale.
  4. Chiamiamo la funzione test per stampare il valore della variabile globale.

In C, quando gli argomenti vengono passati ai parametri della funzione, i parametri agiscono come variabili locali che verranno distrutte all'uscita dalla funzione.

Quando si utilizza variabili globali, usateli con cautela perchรฉ possono causare errori e possono cambiare in qualsiasi punto del programma. Dovrebbero essere inizializzati prima dell'uso.

Variabili statiche

Le variabili statiche hanno un ambito locale. Tuttavia, non vengono distrutti quando si esce dalla funzione. Pertanto, una variabile statica mantiene il suo valore per sempre ed รจ possibile accedervi quando si reinserisce la funzione. Una variabile statica viene inizializzata quando dichiarata e necessita del prefisso static.

Il seguente programma utilizza una variabile statica:

#include <stdio.h>
void say_hi();
int main() {    
  int i;
  for (i = 0; i < 5; i++) { say_hi();}
   return 0;}
void say_hi() {
  static int calls_number = 1;
  printf("Hi number %d\n", calls_number);
  calls_number ++; }

Il programma visualizza:

Hi number 1
Hi number 2
Hi number 3
Hi number 4
Hi number 5

Funzioni ricorsive

Consideriamo il fattoriale di un numero che si calcola come segue: 6! = 6 * 5 * 4 * 3 * 2 * 1.

Questo calcolo viene eseguito calcolando ripetutamente il fatto * (fatto -1) finchรฉ il fatto non equivale a 1.

Una funzione ricorsiva รจ una funzione che richiama se stessa e include una condizione di uscita per terminare le chiamate ricorsive. Nel caso del calcolo dei numeri fattoriali, la condizione di uscita รจ infatti pari a 1. La ricorsione funziona โ€œimpilandoโ€ le chiamate finchรฉ la condizione di uscita non รจ vera.

Per esempio:

#include <stdio.h>
int factorial(int number);
int main() {    
  int x = 6;
  printf("The factorial of %d is %d\n", x, factorial(x)); 
  return 0;}
int factorial(int number) {
 if (number == 1)    return (1); /* exiting condition */
  else
    return (number * factorial(number - 1));
}

Il programma visualizza:

 The factorial of 6 is 720

Qui di seguito, discutiamo i dettagli del programma:

Funzioni ricorsive

  1. Dichiariamo la nostra funzione fattoriale ricorsiva che accetta un parametro intero e restituisce il fattoriale di questo parametro. Questa funzione si chiamerร  e diminuirร  il numero fino all'uscita, o al raggiungimento della condizione base. Quando la condizione รจ vera, i valori generati in precedenza verranno moltiplicati tra loro e verrร  restituito il valore fattoriale finale.
  2. Dichiariamo e inizializziamo una variabile intera con valoreโ€6โ€ณ e quindi stampiamo il suo valore fattoriale chiamando la nostra funzione fattoriale.

Considera il seguente schema per comprendere meglio il meccanismo ricorsivo che consiste nel chiamare la funzione stessa fino al caso base o all'arrestoping quando la condizione viene raggiunta, dopodichรฉ raccogliamo i valori precedenti:

Funzioni ricorsive

Funzioni in linea

La funzione nella programmazione C viene utilizzata per memorizzare le istruzioni utilizzate piรน frequentemente. Viene utilizzato per modularizzare il programma.

Ogni volta che viene chiamata una funzione, il puntatore dell'istruzione salta alla definizione della funzione. Dopo aver eseguito una funzione, il puntatore dell'istruzione ritorna all'istruzione da cui รจ passato alla definizione della funzione.

Ogni volta che usiamo le funzioni, abbiamo bisogno di qualcosa in piรน pointer head per passare alla definizione della funzione e tornare all'istruzione. Per eliminare la necessitร  di tali teste di puntamento, utilizziamo funzioni inline.

In una funzione inline, una chiamata di funzione viene sostituita direttamente da un codice di programma vero e proprio. Non salta a nessun blocco perchรฉ tutte le operazioni vengono eseguite all'interno della funzione inline.

Le funzioni inline vengono utilizzate principalmente per piccoli calcoli. Non sono adatti quando sono coinvolti calcoli di grandi dimensioni.

Una funzione inline รจ simile alla funzione normale, tranne per il fatto che la parola chiave inline รจ posizionata prima del nome della funzione. Le funzioni inline vengono create con la seguente sintassi:

inline function_name ()
{
    //function definition
}

Scriviamo un programma per implementare una funzione inline.

inline int add(int a, int b)		//inline function declaration
{
	return(a+b);
}
int main()
{
	int c=add(10,20);
	printf("Addition:%d\n",c);
	getch();
}

Produzione:

Addition: 30

Il programma sopra mostra l'uso di una funzione in linea per l'addizione di due numeri. Come possiamo vedere, abbiamo restituito l'addizione di due numeri solo all'interno della funzione inline senza scrivere righe aggiuntive. Durante la chiamata alla funzione abbiamo appena passato i valori sui quali dobbiamo eseguire l'addizione.

DOMANDE FREQUENTI

Il passaggio per valore copia l'argomento nella funzione, quindi le modifiche rimangono locali e la variabile originale non viene modificata. Il passaggio per riferimento passa l'indirizzo della variabile tramite un puntatore, consentendo alla funzione di modificare direttamente i dati originali del chiamante.

Il parametro effettivo รจ il valore o la variabile reale che il chiamante passa durante una chiamata di funzione. Il parametro formale รจ il segnaposto denominato nella definizione della funzione che lo riceve. Vengono abbinati in base alla posizione, primo con primo, secondo con secondo.

La funzione AC restituisce direttamente un solo valore. Per restituire piรน risultati, รจ necessario racchiuderli in una struttura, riempire un array o passare puntatori come argomenti, in modo che la funzione scriva ciascun risultato nelle variabili del chiamante.

Le funzioni offrono riutilizzabilitร , consentendo a un blocco di codice di essere eseguito piรน volte, e modularitร , che permette di suddividere un programma di grandi dimensioni in parti piรน piccole. Inoltre, migliorano la leggibilitร , semplificano i test e il debug e nascondono i dettagli complessi dietro un unico nome, risparmiando tempo di sviluppo.

La funzione main() รจ il punto di ingresso da cui inizia l'esecuzione di ogni programma C. Il sistema operativo la chiama per prima e il suo valore di ritorno, solitamente 0, segnala il successo dell'esecuzione. Puรฒ accettare gli argomenti argc e argv per ricevere argomenti da riga di comando.

La ricorsione รจ adatta a problemi con una struttura naturalmente ripetitiva, come l'attraversamento di alberi o il calcolo fattoriale, producendo codice piรน breve e chiaro. L'iterazione รจ generalmente piรน veloce e utilizza meno memoria perchรฉ evita chiamate ripetute. Scegli la ricorsione per chiarezza, l'iterazione per prestazioni ottimali con input di grandi dimensioni.

Sรฌ. Un assistente di programmazione basato sull'IA puรฒ scrivere una funzione C a partire da un prompt in linguaggio naturale, suggerire parametri e tipi di ritorno e segnalare bug come un valore di ritorno mancante o un argomento non corrispondente. Compilare e testare sempre la funzione generata prima di utilizzarla.

Copilota GitHub Scrive funzioni C, completando il corpo a partire dal nome della funzione o da un breve commento e proponendo dichiarazioni, cicli e chiamate ricorsive. Spesso aggiunge un prototipo corrispondente sopra main(), anche se รจ comunque consigliabile rivedere la logica.

Riassumi questo post con: