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;
}
È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top