質問
HI、
いくつかのいずれかを理解する上で私を助けることができるSQUARE(X)の値が49である理由?
私は、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;
}
解決
ニールバターワース、マークとパベルは正しいです。
SQUARE(++ y)は++ * Yの値の2倍をインクリメントyは、Y ++をするために展開されます。
あなたが遭遇する可能性があり、別の問題:SQUAREは、(A + B)(A + B)*(A + B)が、+(B * A)+ Bではありません+ B * A + Bに展開されます。あなたは、マクロを定義しながら、必要なときに要素の周りに括弧を追加するの世話をする必要があります。#define SQUARE(X)((X)*(X))は少しリスクが少ないです。
(イアン・ケンプは、最初に彼のコメントでそれを書きました)あなたが代わりにこの1のように、インラインテンプレート関数(実行時に劣らず、効率的な)を使用することができます:
template <class T>
inline T square(T value)
{
return value*value;
}
あなたはそれが動作確認することができます
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(記述する必要はありません。
square<int>(++i)
int型はiに対する暗黙的であるため)。
他のヒント
マクロはに展開するのでます:
++y * ++y
C ++で未定義の動作を与える - 結果はできます 何もします。これは非常によく知られた問題は、マクロの使用をカバーしてまともな教科書でカバーされるべきです。あなたはどちらを使用していますか?
あなたが書いたコードは
に拡大しますprintf("%d\n",++y * ++y );
とコンパイラは2インクリメントし、その後乗算
を見て、このように、次に動作の順序は未定義の動作でありますだから、インライン展開することができ、コンパイラとして実行するために、任意の時間がかかりません関数を使用するより良いマクロに注意してください。
第二に、あなたが変数をインクリメントし、使用している場合は何が起こるか想定していません。
マクロは関数ではありません。彼らはプログラムのテキストを変更します。この操作は、のの前処理と呼ばれ、あなたのコードがコンパイルされる前に、それが自動的に実行されます。人々は自分の時間を節約し、そのソースコードにいくつかの変動を導入するマクロを記述します。
あなたがSQUARE(x)
を書くとき、、実際のfuncitonコールは、単にテキストが変更され、起こりません。操作は非常にダムであるので、あなたはあなたのようなケースでは、追加の予防措置を行う必要があります。あなたのケースの説明については、他の回答を参照してください。