2016-11-02 20 views
1

私はこのことについて非常に紛らわしいです:マクロと同様の機能異なる結果を返す

#define prod(x,y) x*y 

次の関数呼び出しを印刷コンソールで11

printf("%d",prod(1+2,3+4)); 

をしかし、私は関数としてprod(x,y)を使用x*yを返すと、21を返します。 結果が異なるのはなぜですか?私は#defineprod(x,y) = x*yを与えるべきだと思った。

+2

単純な数学。 '1 + 2 * 3 + 4'は11です。定義は関数ではなく、単純なテキスト置換です。 – tkausl

+0

半分くらいのCの本には、このような例があり、それがうまくいかない理由とかっこで固定する方法を説明します。 – Lundin

+0

[関数とマクロの使用時に異なる結果になるのはなぜですか?](http://stackoverflow.com/questions/20182897/why-do-i-get-different-results-when-using-a関数対マクロ) –

答えて

2

オペレータの優先順位はあなたを噛んでいます。

#define prod(x,y) x*y 

printf("%d",prod(1+2,3+4)); 

*+より高い優先順位を有すること

printf("%d",1+2*3+4); 

注に拡張されます、これは1 + (2 * 3) + 4又は11として評価されます。

ソリューション:

Surrroundあなた#defineでカッコパラメータ:

printf("%d",((1+2)*(3+4))); 

の余分なセットの目的:

#define prod(x,y) ((x)*(y)) 

ラインは、今まで展開されます式全体の括弧は、結合式で使用するときに必要なように式を動作させることです評価の順序が重要なオペレータとの間で

prod(4,3)/prod(1,2))は、((4)*(3))/((1)*(2))または6に拡張されます。外かっこがなければ、展開は(4)*(3)/(1)*(2)または24になります。

#define prod(x,y) x*y 

のあなたの定義と

1

マクロによれば、prod(1+2,3+4)は、1+2*3+4に拡張され、11に等しくなります。それを修正するために括弧を使用してください:

#define prod(x, y) ((x)*(y)) 
1

ライン

printf("%d",prod(1+2,3+4)); 

printf("%d",1+6+4); 
と評価されます

printf("%d",1+2*3+4); 

なり

収量

11 

関数が物事を別々に評価します。機能

int prod(int x, int y) { return x*y; } 

でコール

printf("%d",prod(1+2,3+4)); 

は、彼らは渡すことができるパラメータの前に(評価)崩壊する必要があります。これは、Cがパラメータ処理スタイルで「値渡し」であるためです。技術的に参照されているポインタさえも参照を表す値に変換され、それらの値は渡されます。だから、呼び出しが

return 3*7; 

または 復帰21

なっ関数の内部で、ここで旅行の一番の教訓があります

printf("%d",prod(3,7)); 

に減少します。 マクロは言語を理解していません。これは単なるテキストの置換であり、タイプ、演算子の優先順位、または学習に時間を割いた他の言語要素を尊重するものではありません。基本的に、マクロ言語はC言語とは異なり、C言語よりもはるかに原始的な言語です。

関連する問題