2015-08-09 15 views
5
#include <stdio.h> 

#define sqr(a) a*a 

int main() 
{ 
    int i; 

    printf("%d",64/sqr(4)); 

    return 0; 
} 

Perché ottengo l'uscita come 64.Non riesco a comprendere l'esecuzione del seguente codice c

Normalmente ciò che dovrebbe accadere è innanzitutto verificare il valore per sqr(4) e quindi dividere. In caso di qualsiasi altro operatore funziona bene.

Spiegare per favore.

risposta

6

Dopo la trasformazione della linea printf sarà:

printf("%d",64/4*4); 

che dovrebbe spiegare perché stampa 64.

Usare sempre parentesi nelle definizioni macro quando contengono espressioni:

#define sqr(a) ((a)*(a)) 

Anche questo non è sicuro contro invocazioni macro come: sqr(x++). Quindi non usare marcos a meno che non sia necessario :)

0

Le macro non sono funzioni, sono (per lo più) sostituzione di testo stupida. La macro manca parentesi, in modo che quando il preprocesor lo sostituisce, si otterrebbe il seguente:

printf("%d",64/4*4); 

Dal / e * hanno la stessa precedenza, questo è come affermando (64/4)*4, che è, ovviamente, 64.

Se si desidera che il macro sqr far quadrare in modo sicuro il suo argomento, avvolgerlo in parentesi:

#define sqr(a) (a*a) 
0

64/sqr(4) viene espansa per 64/4*4.

dovete parenthetise corpo macro e dovrebbero anche mettere tra parentesi aroud l'argomento:

#define sqr(a) ((a)*(a)) 

Resa: 64/(4*4)

Nota che le macro sono puri testuali sostituzioni effettuate dal C preprocessoreprima dello inizia la compilazione effettiva.

Un approccio migliore e type-safe sarebbe quella di utilizzare una funzione inline:

static inline int sqr(int a) 
{ 
    return a * a; 
} 

Questo sarà probabilmente inline nel codice chiamante dal compilatore tanto quanto la macro sarebbe. OTOH, il compilatore potrebbe benissimo decidere di non farlo, a seconda dell'euristica interna. In generale, è necessario affidarsi al compilatore per utilizzare il modo corretto, a meno che non si verifichino seri problemi di prestazioni/dimensioni del codice.

Questo proteggerà anche contro la valutazione dell'argomento a due volte. Cioè critica se ci sono effetti collaterali come

int i[2], *p = i; 
sqr(*p++); 

Per la versione macro, questo si tradurrà in un comportamento indefinito (ordine indefinita di valutazione):

((*p++) * (*p++)) 
Problemi correlati