Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
I corsi di Scienze Matematiche Fisiche e Naturali
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Salvatore Cuomo » 8.Il linguaggio C – funzioni e puntatori


Linguaggio C – funzioni esempio 1

Problema

Scrivere una funzione di tipo main che richiami una funzione di tipo int denominata pot_ennesima che calcoli la potenza n-ma di assegnato numero intero.

Codice_C_1

Codice_C_1


Nota esempio 1

Struttura di una funzione

Di seguito si riporta la specifica della funzione che si vuole costruire. Si osservi che prima di iniziare il main la funzione viene dichiarata secondo le proprie caratteristiche strutturale. Ovvero “in gergo” diremo che abbiamo scritto il prototipo della funzione.

int pot_ennesima(int base, int n)

  1. int è il tipo del valore che la funzione deve ritornare;
  2. pot_ennesima è il nome della funzione ed memorizza il valore di ritorno;
  3. int base, int n rappresentano i parametri di ingresso, ovvero i valori di input, passati alla funzione. In questo esempio abbiamo due parametri interi in input.

Nota esempio 1 cont

La funzione
Un funzione viene richiamata attraverso una istruzione del tipo:

potenza = pot_ennesima(2,i);

nel programma di tipo main. L’inzio e la fine della funzione sono individuati dalla apertura e dalla chiusura di parentesi graffe:

int pot_ennesima(int base, int n){
...
return p;
}

L’istruzione return p restituisce in output alla funzione chiamante main() il valore di output p attraverso il nome della funzione.

N.B. Si osservi che se la funzione è di fissato tipo (ad esempio int) il valore ritornato (quello a fianco a return) deve essere dello stesso tipo (nel nostro caso int).

Linguaggio C – funzioni esempio 2

Problema

Scrivere una funzione di tipo main che richiami una funzione di tipo int denominata scambio che scambi il valore di due variabili di tipo float.

Codice_C_2

Codice_C_2


Nota esempio 1

Passaggio di parametri ad una funzione
Se si prova ad eseguire il precedente codice avviene che programma non dà il risultato atteso. Si ottiene infatti:

a=3 b=5

Quello che avviene è mostrato in figura.

Ovvero:

  1. le variabili a e b in fissati indirizzi di memoria vengono “copiate” nelle variabili x e y che risiedono in differenti indirizzi;
  2. la funzione effettua lo scambio in memoria delle variabili;
  3. la funzione ritorna il controllo al main.

In C il passaggio dei parametri avviene per valore non per indirizzo di memoria.

Passaggio per riferimento.

Passaggio per riferimento.


Puntatori

Passaggio di parametri ad una funzione

In C il passaggio dei parametri avviene per valore non per indirizzo di memoria.

I Puntatori:
Nel linguaggio C esistono della “variabili speciali”, dette puntatori, che contengono l’indirizzi di memoria.

Nell’esempio in figura si vede che la variabile p contiene l’indirizzo in memoria della variabile x. Potremo dire che p è una variabile che memorizza il numero civico dell’abitazione di x.
In generale, si dice che p punta ad x o anche che p è un puntatore per x.

Memorizzazione variabili.

Memorizzazione variabili.


Puntatori cont

p è un puntatore alla variabile x, ovvero p è una variabile che contiene l’indirizzo della variabile x.
L’istruzione

p = &x;

assegna l’indirizzo di x (nell’esempio 10001) alla variabile puntatore p da questo momento p punta a x.

Per conoscere il valore della variabile puntata da p ( nell’esempio il valore di x che è 5 ) si utilizza l’operatore unario *. In particolare:

*p

è il contenuto dell’area di memoria puntata da p, cioè nel nostro esempio *p vale 5 ossia il valore della variabile x.

Puntatori cont (segue)

Una variabile puntatore deve essere dichiarata necessariamente allo scopo a cui è adibita.

Ad esempio se si dichiara all’inizio di una funzione:

int *p;

p è una variabile puntatore ad una locazione di memoria di tipo intero.

Esempio:

  1. int x=5; /* dichiarazione della variabile x */
  2. int *p; /* dichiarazione del puntatore p */
  3. p=&x; /* assegnazione a p dell’indirizzo di x */
  4. *p=3;/* assegnazione al contenuto della variabile puntata da p del valore 3*/
Memorizzazione puntatori.

Memorizzazione puntatori.


Esempio di utilizzo dei puntatori

Vediamo con qualche esempio come sia possibile manipolare dei puntatori:

  1. int x=1, y=2, z[10];
  2. int *p; /* dichiarazione del puntatore p */
  3. p = &x; /* p ora punta a x */
  4. y = *p; /* y ora vale 1 */
  5. *p = 0; /* x ora vale 0 */
  6. p = &z[0]; /* p ora punta a z[0] */

Nell’esempio p è un puntatore utilizzato al punto 3 per individuare la variabile x e al punto 6 per puntare alla variabile z[0].

Esempio di utilizzo dei puntatori (segue)

I puntatori possono apparire nelle espressioni, ad esempio:

  1. int x,y, *p;
  2. p=&x;
  3. y = *p +1; /* equivale a y = x+1; */
  4. *p += 1; /* equivale a x = x+1; */
  5. *p = 10; /* equivale a x=10; */

Se q è un altro puntatore ad una variabile intera, l’istruzione

q = p;

copia il contenuto di p in q. In base a quanto detto questo significa che q punta alla stessa variabile a cui punta p.

Esempio 2 versione corretta

Problema

Scrivere una funzione di tipo main che richiami una funzione di tipo int denominata scambio che scambi il valore due variabili di tipo float.

Codice_C_3

Codice_C_3


Nota esempio 2

Passaggio di parametri ad una funzione per indirizzo
Se si prova ad eseguire il precedente codice con la chiamata:

scambio(&a, &b)

gli indirizzi delle variabili a e b vengono “copiati” nelle variabili px e py.
i puntatori px e py scambiano il loro valore ovvero gli indirizzi che contengono
la funzione ritorna il controllo al main.

In C il passaggio dei parametri per indirizzo si ottiene utilizzando nella chiamata l’operatore &.

Passaggio per indirizzi.

Passaggio per indirizzi.


Array e puntatori

Array
Esiste una stretta correlazione tra array e puntatori. Con l’istruzione:

int a[10], *pa;

Viene allocato un vettore di interi di lunghezza 10 ed un puntatore ad intero. Per puntare all’array è sufficiente l’istruzione:

pa = &a[0];

E’ possibile accedere agli elementi del vettore a attraverso il puntatore pa. Inoltre:

  • pa+1 è l’indirizzo di a[1] mentre *(pa+1) è il contenuto di a[1]
  • pa+i è l’indirizzo di a[i] mentre *(pa+i) è il contenuto di a[i]
Array e puntatori 1.

Array e puntatori 1.

La figura mostra schematicamente come pa punta ad a.

La figura mostra schematicamente come pa punta ad a.


Array e puntatori (segue)

Array

Per definizione il nome di un array è l’indirizzo del primo elemento dell’array, per cui nell’esempio il nome:

a

rappresenta l’indirizzo del vettore a[10], è dunque esso stesso un puntatore. Riportiamo alcuni esempi di utilizzo di array e puntatore:

  • a[i] equivalente *(a+i)
  • &a[i] equivalente a+i
  • pa = &a[0]; equivalente pa = a;
  • *(pa+i) equivalente pa[i]
Array e puntatori 2.

Array e puntatori 2.


Array e puntatori (segue)

Nota

Si deve però tenere presente che:

  1. un puntatore è una variabile;
  2. il nome di un array è una costante.

Secondo tale osservazione si evince che:

pa=a; pa++;

sono istruzioni consentite.

Mentre

a=pa; a++;

non sono delle istruzioni consentite.

Funzioni ed array

Passaggio di un array ad una funzione
Se il nome di un array è passato come argomento ad una funzione, in realtà è passato l’indirizzo del primo elemento dell’array. Per cui ad esempio si può ragionare nella seguente maniera:

main()
{
int a[3];
...
fun(a);
...
}

Il prototipo della funzione può essere strutturato in uno dei seguenti modi:

  • int fun(int arr[3]);
  • int fun(int arr[]);
  • int fun(int *arr);

Linguaggio C – esempio 3 versione puntatori

Problema

Scrivere una funzione di tipo main che sommi due vettori di reali memorizzati secondo in strutture dati di tipo array statico.

Codice_C_4

Codice_C_4


  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion