2016-03-14 2 views
30

Herbert Schildt dice:Cos'è la valutazione degli argomenti?

In alcune situazioni, funzione reale dovrebbe essere utilizzata al posto della funzione-like-macro, ad esempio: dove le dimensioni del codice deve essere minimizzato o dove un argomento non deve essere valutato più di una volta.

Cosa intende per "un argomento non deve essere valutato più di una volta?"

+8

Schildt è [visto scettico da alcuni] (https://en.wikipedia.org/wiki/Herbert_Schildt#Reception). Basta dire. – DevSolar

+3

@DevSolar: Non conosco quel libro, ma se l'affermazione citata è tipica dello stile, sono pienamente d'accordo con gli scettici. – Olaf

+0

@DevSolar Volevi dire [scettico] (https://www.google.com/search?q=define%3Askeptical), giusto? Oppure lo hai scritto con una [C] (https://en.wikipedia.org/wiki/C_ (programming_language)) perché questa domanda è codificata [tag: c] e non [tag: k]? : P – cat

risposta

50

Diamo una macro per calcolare il massimo di due valori:

#define MAX(a, b) ((a) < (b) ? (a) : (b)) 

Poi usiamo in questo modo:

int x = 5; 
int y = 10; 
int max = MAX(x++, y++); 

Poi la macro viene espansa per

int max = ((x++) < (y++) ? (x++) : (y++)); 

Come si può vedere, l'operazione di incremento su x o y avverrà due volte, non cosa succederebbe se avessi una funzione in cui ogni argomento che passi viene valutato solo una volta.


Un altro punto importante è l'uso di parentesi nella macro. Prendiamo un altro semplice macro:

#define MUL(a, b) a * b 

Ora, se si richiama la macro come

int sum = MUL(x + 3, y - 2); 

quindi l'espansione diventa

int sum = x + 3 * y - 2; 

Quale causa operator precedence è pari a

int sum = x + (3 * y) - 2; 

Spesso non proprio quello che ci si aspettava, se ci si aspetta (x + 3) * (y - 2).

Questo problema viene anche "risolto" utilizzando le funzioni.

+0

Penso che quello che hai detto sia opposto. Per la funzione chiamata 'max (x, x ++)', 'x' viene valutata due volte, quindi in questo caso l'uso della macro andrà bene. Nella macro chiamata 'MAX (x ++, y ++);', nessuno degli argomenti è stato valutato più di una volta. – haccks

+5

@haccks Che non è corretto. Come dice Joachim nella sua risposta 'MAX (x ++, y ++)' è espanso in '((x ++) <(y ++)? (X ++): (y ++));' ed è quindi valutato due volte. La funzione corrispondente 'max (x ++, y ++)', ogni argomento viene valutato solo una volta – vu1p3n0x

+3

@haccks Sia le espressioni 'x ++' che 'y ++' vengono valutate come parte della condizione. Quindi uno dei due 'x ++' o 'y ++' viene valutato ancora una volta a seconda della condizione nell'espressione ternaria. –

4

A volte gli argomenti hanno effetti .

Ad esempio, il valore di i++ è i, ma i viene aumentato di 1. Di conseguenza, il valore della prossima i++ sarà i + 1.

In una macro, gli argomenti vengono valutati ogni volta che viene richiesto, causando i valori risultanti; In una funzione, gli argomenti (effettivi) vengono valutati e copiati in argomenti (formali) all'interno della funzione, ignorando gli effetti collaterali.

Quando si implementa una funzione, non si preoccupano degli effetti collaterali. Tuttavia, la promozione e il casting impliciti del tipo potrebbero invece essere soggetti a errori.