Estratto del documento

DICHIARAZIONE DI UNA FUNZIONE (PROTOTIPO)

La dichiarazione di una funzione, nota anche come prototipo, è come un "biglietto da

visita" della funzione. Il suo scopo è specificare al compilatore come deve essere

utilizzata la funzione prima che questa venga effettivamente definita.

- Sintassi: La sintassi generale è tipo_ritorno nome_funz (tipo_par1, ...,

tipo_parN);.

- Componenti:

tipo_ritorno: Indica il tipo di valore che la funzione restituirà al programma

chiamante al termine della sua esecuzione. Ad esempio, se la funzione calcola

un numero intero, il tipo_ritorno sarà int.

nome_funz: È il nome identificativo della funzione, quello che useremo per

richiamarla.

Parentesi (): Racchiudono la lista dei parametri.

Lista dei parametri: Contiene il tipo di ciascun parametro che la funzione si

aspetta di ricevere. Opzionalmente, si può specificare anche il nome del

parametro, ma non è strettamente necessario nella dichiarazione (tipo [nome]).

- Caso void: Se il tipo_ritorno è void, significa che la funzione non restituisce alcun

valore al chiamante. In questo caso, la funzione viene genericamente chiamata

procedura

DEFINIZIONE DI UNA FUNZIONE

La definizione di una funzione è la parte in cui si scrive il codice effettivo che la

funzione eseguirà. È qui che si implementa la logica della funzione. Questa fase

prevede

- Sintassi: tipo_ritorno nome_funz (tipo_par1 par1, ..., tipo_parN parN) { ...corpo

della funzione... }.

- Parametri formali: I parametri dichiarati nella definizione (es. par1, parN) sono

chiamati parametri formali.

- Importanza dei parametri:

È importante l'ordine in cui sono dichiarati.

È importante il tipo di ciascun parametro.

È importante riconoscere se un parametro è di ingresso (la funzione lo usa), di

uscita (la funzione lo modifica per restituire un risultato) o di ingresso-uscita (lo

usa e lo modifica).

CHIAMATA DI UNA FUNZIONE

Per utilizzare una funzione, è necessario chiamarla (o invocarla) dal programma

principale (main) o da un'altra funzione. Durante la chiamata, si passano i parametri

effettivi, che sono i valori o le variabili che la funzione userà per la sua esecuzione.

•Requisiti dei parametri effettivi:

◦Devono avere lo stesso tipo della dichiarazione (o tipi compatibili per conversione

implicita).

◦Devono essere passati nello stesso ordine della dichiarazione.

◦Il loro nome può essere anche diverso dai nomi dei parametri formali.

ALLOCAZIONE DI MEMORIA E VISIBILITA’ DELLE VARIABILI

Quando una funzione viene chiamata, il sistema gestisce la memoria in un modo

specifico:

1.Viene allocato spazio in memoria per i parametri formali della funzione chiamata.

2.Il valore dei parametri effettivi viene copiato negli spazi allocati per i rispettivi

parametri formali. Questo è il meccanismo del "passaggio per valore".

3.Viene allocato spazio per le variabili locali dichiarate all'interno della funzione.

4.La funzione viene eseguita.

5.Al termine dell'esecuzione della funzione, lo spazio delle variabili locali viene

deallocato.

6.Successivamente, lo spazio dei parametri formali viene deallocato.

7.L'esecuzione procede con il programma chiamante (ad esempio, il main).

Osservazioni cruciali:

Alla funzione vengono passati i valori dei parametri effettivi, non le variabili stesse.

Di conseguenza, tutti i cambiamenti effettuati sulle variabili locali e sui parametri

formali all'interno della funzione vengono persi una volta che la funzione termina la

sua esecuzione.

Questo comportamento è ideale per i parametri di ingresso, poiché la funzione usa i

valori ma non modifica le variabili originali.

Tuttavia, può rappresentare un problema per i parametri di uscita, poiché se si

desidera che la funzione modifichi una variabile nel chiamante, il semplice passaggio

per valore non è sufficiente.

•Variabili globali e locali: Il documento ribadisce che anche la funzione main è una

funzione come le altre. Si sconsiglia l'uso di variabili globali se non assolutamente

necessario, poiché possono rendere il codice più difficile da gestire e "debuggare" a

causa della loro visibilità da qualsiasi parte del programma.

PARAMETRI DI USCITA: IL CASO DEL VETTORE

La gestione dei vettori (array) come parametri di funzione ha una peculiarità:

•Quando si passa un vettore a una funzione (ad esempio, per stamparlo o leggerne gli

elementi), si dichiara la funzione in un modo simile a void stampa(int v[], int n); o void

stampa(int v, int n);.

•Alla chiamata, si passa semplicemente il nome del vettore, ad esempio

stampa(vettore, 100);.

•Cosa viene passato? A differenza delle variabili primitive (come int, float), quando si

passa un vettore, non viene copiato l'intero vettore. Viene invece passato l'indirizzo

del primo elemento del vettore in memoria

•Cosa comporta? Questo significa che la funzione opera direttamente sulla memoria

del vettore originale [non esplicitamente detto nella fonte, ma implicito dal

comportamento che segue e dalla domanda "Cosa comporta?" in]. Pertanto, qualsiasi

modifica apportata agli elementi del vettore all'interno della funzione sarà visibile

anche nel programma chiamante dopo che la funzione è terminata. Questo rende i

vettori un'eccezione al "passaggio per valore" generale e li rende adatti a fungere da

"parametri di uscita" impliciti, permettendo alla funzione di popolare o modificare dati

che saranno poi usati dal chiamante. Il documento lo suggerisce ponendo le domande

"Parametri di ingresso?" e "Parametri di uscita?" in.

Il documento introduce il problema di come gestire più parametri di uscita da una

funzione. L'esempio classico è lo scambio di due variabili (swap).

•Un tentativo intuitivo di implementare swap (es. void swap(int a, int b) { int temp =

a; a = b; b = temp; }) non funziona come desiderato. Questo perché, come spiegato

prima, i cambiamenti ai parametri formali a e b vengono persi al termine della

funzione, e le variabili originali nel chiamante rimangono inalterate.

•Il documento conclude questa sezione affermando che si ritornerà su questo

problema dopo aver studiato i puntatori. I puntatori sono il meccanismo in C che

permette di passare l'indirizzo di una variabile a una funzione, consentendo alla

funzione di accedere e modificare direttamente il valore della variabile originale nel

contesto del chiamante, risolvendo così il problema dei parametri di uscita multipli o

della modifica di variabili primitive.

OVERLOAD DELLE FUNZIONI

Il termine "overload" (o sovraccarico) si riferisce alla capacità di avere funzioni diverse

che condividono lo stesso nome ma si distinguono per altri aspetti. In generale, in

programmazione (e in C, per quanto riguarda le convenzioni del compilatore), funzioni

diverse possono distinguersi per:

•Il nome (es. somma vs max).

•Il numero dei parametri (es. float somma(float a, float b); vs float somma(float a, float

b, float c);).

•L'ordine dei parametri (es. funzione(int a, float b); vs funzione(float a, int b);).

•In C, le funzioni sono identificate principalmente dal loro nome e dai tipi/numero dei

loro parametri. Il tipo di ritorno non è sufficiente da solo a distinguere due funzioni con

lo stesso nome e gli stessi parametri (sebbene il documento mostri esempi come float

somma(float a, float b); e double somma(float a, float b); dove il tipo di ritorno è

l'unica differenza apparente tra funzioni con lo stesso nome e stesso numero/tipo di

parametri, in C puro questo non è "overloading" nel senso di C++, ma semplicemente

funzioni con lo stesso nome che il compilatore potrebbe non distinguere facilmente

senza altri meccanismi come la firma completa che include il tipo di ritorno per alcune

implementazioni o l'uso di linkaggio esterno che distingue per nome mangiato).

FILE

Le variabili in C esistono solo durante l'esecuzione del programma: una volta

terminato, tutti i dati contenuti in esse vengono persi. È necessario quindi introdurre il

concetto di file.

Un file è una unità di memorizzazione dati gestita dal FileSystem.

Il suo scopo principale è consentire la memorizzazione di informazioni su memorie di

massa (come dischi o CD) in modo non volatile, così che i dati memorizzati nelle

variabili di un programma non vanno persi al termine dell'esecuzione del programma

Concettualmente, un file è una sequenza di registrazioni uniformi, ovvero dello stesso

tipo. Possono essere visti come un'astrazione di

memorizzazione con una dimensione potenzialmente illimitata (ma non infinita) e un

accesso sequenziale.

A livello di sistema operativo, ogni file è identificato in modo univoco dal suo nome

assoluto, che include il percorso e il nome relativo. I dati all'interno di un file sono

salvati come byte

Esistono due tipologie di file:

- File di testo: Ogni byte è la rappresentazione ASCII di un carattere.

n pratica, è come leggere un normale documento di testo: quello che si vede è

esattamente quello che è contenuto nel file.

In C, un flusso di testo è una sequenza di caratteri, spesso organizzata in righe

che finiscono con il carattere speciale di "a capo" (\n).

Quando scriviamo un numero in un file di testo (per esempio un int), il numero

viene convertito in caratteri. Ad esempio, il numero 123 viene memorizzato

come i caratteri '1', '2' e '3'. Questo significa che lo spazio occupato nel file

dipende dal valore del numero.

- File binari: Ogni byte è la rappresentazione dell'informazione specifica

dell'applicazione (ad esempio, Word, Excel). Nel linguaggio C, un flusso binario è

semplicemente una sequenza di byte, esattamente uguale a come i dati sono

memorizzati nella RAM del computer. Non ci sono conversioni in caratteri o

formattazioni.

Nel linguaggio C, i file sono visti come sequenze lineari di byte. Il C offre solo alcune

funzioni di base per operare sui file. È importante notare che nel C non esiste il

concetto di record o di chiave di ricerca e, di conseguenza, non ci sono funzioni

predefinite per l'inserimento, la modifica, la cancellazione o la ricerca di record

all'interno di un file. Le operazioni consentite sono

- la creazione

- rimozione

- lettura

- scrittura di byte/testo da/su file

Quando un programma in C deve leggere o scrivere qualcosa, non si collega

direttamente al dispositivo fisico (come hard disk o monitor). Viene infatti utilizzato un

canale intermedio che prende il nome di flusso o stream. Dobbiamo seguire tre

passaggi fondamentali

Anteprima
Vedrai una selezione di 3 pagine su 7
Sottoprogrammi Pag. 1 Sottoprogrammi Pag. 2
Anteprima di 3 pagg. su 7.
Scarica il documento per vederlo tutto.
Sottoprogrammi Pag. 6
1 su 7
D/illustrazione/soddisfatti o rimborsati
Acquista con carta o PayPal
Scarica i documenti tutte le volte che vuoi
Dettagli
SSD
Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher sav.lis di informazioni apprese con la frequenza delle lezioni di Elementi di programmazione e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli studi della Campania "Luigi Vanvitelli" o del prof Cesario Vincenzo Angelino.
Appunti correlati Invia appunti e guadagna

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community