18.08.2013 Views

Dalla A alla Z passando per C - Robotica

Dalla A alla Z passando per C - Robotica

Dalla A alla Z passando per C - Robotica

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

void swap(int *a, int *b)<br />

{<br />

int tmp;<br />

}<br />

tmp = *a;<br />

*a = *b;<br />

*b = tmp;<br />

Gli argomenti delle funzioni possono essere tipi semplici o strutture dati e, come detto, sono<br />

sempre passati <strong>per</strong> valore; anche se è consentito, normalmente non vengono passate strutture<br />

dati né come argomenti né come valori di ritorno. Si preferisce invece, <strong>per</strong> ragioni di efficienza,<br />

allocare le strutture dati separatamente e passare solo i puntatori ad esse, effettuando così un<br />

passaggio <strong>per</strong> riferimento.<br />

Perchè si parla di questioni di efficienza? Come detto, il passaggio dei parametri che avviene<br />

<strong>per</strong> valore comporta l’allocazione di una copia locale delle variabili dichiarate nella lista dei<br />

parametri. Oltre all’allocazione, tali variabili devono anche essere inizializzate <strong>per</strong> riflettere il<br />

valore delle variabili o espressioni del chiamante. Questo comporta, nel caso in cui il parametro<br />

passato sia una variabile, la copia esplicita di una porzione di memoria d<strong>alla</strong> variabile utilizzata<br />

<strong>per</strong> la chiamata <strong>alla</strong> variabile locale. Nel caso le variabili siano strutture dati c’è quindi una<br />

<strong>per</strong>dita di efficienza nel passaggio dei parametri che è proporzionale <strong>alla</strong> dimensione della variabile,<br />

in quanto il tempo necessario <strong>alla</strong> copia del valore aumenta all’aumentare della dimensione<br />

della struttura.<br />

Un altro caso in cui è utilizzato il passaggio <strong>per</strong> riferimento è nel caso in cui una funzione<br />

debba ritornare più di un valore, <strong>per</strong> esempio un numero intero e un codice di errore. Anche<br />

in questo caso è possibile utilizzare il passaggio <strong>per</strong> riferimento e passare quindi dei puntatori<br />

come argomenti ulteriori, in modo che la funzione possa scrivere i valori di ritorno in una o più<br />

variabili del chiamante. Esempio:<br />

int findid(struct obj *item, int *errorptr)<br />

{<br />

if (isvalid(item) == 0) {<br />

*errorptr = ERR_INVALID;<br />

return 0;<br />

}<br />

*errprptr = ERR_NOERROR;<br />

return internal_findid(item);<br />

}<br />

Nell’esempio precedente, la funzione findid viene utilizzata <strong>per</strong> trovare un valore intero all’interno<br />

della struttura passata come argomento (anche la struttura è passata <strong>per</strong> riferimento, <strong>per</strong> i<br />

motivi di efficienza appena illustrati). Quindi il tipo restituito d<strong>alla</strong> funzione findid è intero. Per<br />

ricercare il valore, findid si appoggia <strong>alla</strong> funzione internal_findid, che accetta il puntatore<br />

<strong>alla</strong> struttura come parametro. Prima di chiamare internal_findid, findid effettua dei controlli<br />

di validità sulla struttura, in quanto internal_findid si aspetta in ingresso una struttura<br />

corretta. Inoltre, internal_findid deve notificare al chiamante il fatto di aver ricevuto o meno<br />

una struttura corretta, in modo che il chiamante non interpreti erroneamente il valore di ritorno<br />

di findid. Ecco che il secondo parametro di findid viene modificato internamente <strong>alla</strong> funzione<br />

<strong>per</strong> assegnargli il codice di errore e, di fatto, ritornare un secondo valore di uscita. Un possibile<br />

uso della funzione dell’esempio è il seguente:<br />

98

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!