Domanda
HI,
Qualcuno può aiutarmi a capire il motivo per cui il valore di SQUARE (x) è 49?
Sto usando Visual C ++ 6.0.
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}
Soluzione
Neil Butterworth, Marco e Pavel hanno ragione.
SQUARE (++ y) si espande a ++ y * y ++, che incrementa il doppio del valore di y.
Un altro problema si potrebbe incontrare: SQUARE (a + b) si espande a un + b * a + b che non è (a + b) * (a + b), ma a + (b * a) + b. Si dovrebbe prendere cura di aggiungere parentesi attorno elementi quando necessario mentre la definizione di macro: #define SQUARE (X) ((X) * (X)) è un po 'meno rischioso. (Ian Kemp lo ha scritto prima nel suo commento)
Si potrebbe utilizzare invece una funzione di modello di linea (non meno efficace in fase di esecuzione) come questo:
template <class T>
inline T square(T value)
{
return value*value;
}
È possibile controllare funziona:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(non c'è bisogno di scrivere
square<int>(++i)
perché il tipo int è implicito per i)
Altri suggerimenti
Poiché la macro si espande a:
++y * ++y
che dà un comportamento indefinito in C ++ - il risultato potrebbe essere qualsiasi cosa. Questo problema ben noto dovrebbe essere coperto in ogni libro di testo decente che copre l'uso di macro. Quale stai usando?
A causa delle macro fanno sostituzione testuale in modo che il codice è scritto viene espansa a
printf("%d\n",++y * ++y );
e quindi l'ordine delle operazioni è un comportamento indefinito quindi questo il compilatore vede incrementi di 2 e quindi una moltiplicazione
Quindi state attenti con le macro meglio usare le funzioni che, come il compilatore può espandersi in linea non vi porterà più a correre.
In secondo luogo non si assumono che cosa accadrà se si incrementa e utilizzare le variabili
Le macro non sono funzioni: hanno appena modificare il testo del programma. Questa operazione viene chiamata di pre-elaborazione ed è eseguita automaticamente prima il codice viene compilato. La gente scrive macro per salvare il loro tempo e introdurre una certa variabilità al loro codice sorgente.
Quando si scrive SQUARE(x)
, nessuna chiamata funciton reale accade, solo il testo viene modificato. Il funzionamento è abbastanza stupido, quindi bisogna fare ulteriori precauzioni in casi come la tua. Fare riferimento alle altre risposte per visualizzare la spiegazione del vostro caso.