7

以下のコードの答えが 16 なのはなぜですか? このプログラムの動作を説明できる人はいますか?

#define SQUARE(n) n*n
void main()
{
    int j;      
    j =16/SQUARE(2);

    printf("\n j=%d",j);
    getch();
}

以下のように同じコードを書くと、答えは 4 です。

//the ans is 4 why?
#include<stdio.h>
#include<conio.h>

#define SQUARE(n) n*n

void main()
{
    int j;      
    j =16/(SQUARE(2));

    printf("\n j=%d",j);
    getch();
}
4

9 に答える 9

16

プリプロセッサは、記述されたとおりにテキストを置き換えるだけです。

したがって、マクロ呼び出しSQUARE(2)は文字通りになり2*2ます。

あなたの場合、それは式全体が16/2*2になることを意味します。これは、Cの優先順位規則により、(16/2)* 2、つまり16と評価されます。

マクロは常に括弧で囲む必要があり、各引数も同様に囲む必要があります。

そうすると、次のようになります。

#define SQUARE(n)  ((n) * (n))

これはに置き換えられ16/((2) * (2))、16/4、つまり4と評価されます。

各引数の周りのparensはSQUARE(1+1)、期待どおりに機能するようにします。それらがないと、次のような呼び出し16/SQUARE(1+1)は発生しません。16/(1+1*1+1)つまり16/3、必要なものはまったくありません。

于 2013-01-30T13:21:29.073 に答える
3

1.式として使用するマクロを使用する場合は、マクロ本体全体を括弧で囲む必要があります。

これにより、次のような誤った拡張が防止されます。

#define SQUARE(x) x*x
-SQUARE(5,5)
// becomes -5 * 5

2.マクロ引数が式である場合は、それらも括弧で囲む必要があります。

これにより、さまざまなタイプの問題が防止されます。

#define SQUARE(x) x*x
SQUARE(5+2)
// becomes 5 + 2*5 + 2

したがって、正しい方法は次のように書くことです。

#define square(n) ((n)*(n))
-SQUARE(5+2)
// becomes -((5+2)*(5+2))

ただし、マクロを関数として使用することはお勧めしません(理由を推測します)ので、代わりに関数を使用してください。例えば:

inline double square(n) { return n*n; }
于 2013-01-30T13:21:10.033 に答える
3

次のように、絶縁括弧でマクロを定義する必要があります。

 #define SQUARE(n) ((n)*(n))

さもないと

 j = 16/SQUARE(2);

に展開します

j = 16 / 2 * 2;   which is equivalent to (16 / 2) * 2

欲しいものがあるとき

j = 16 / (2 * 2);   
于 2013-01-30T13:18:07.777 に答える
3

操作の順序。あなたの式は次のように評価されます:

 j = 16 / 2 * 2

これは 16 に相当します。次のようにします。

#define SQUARE(n) (n*n) 

これにより、正方形が最初に評価されます。

于 2013-01-30T13:19:58.933 に答える
2

マクロは次のように展開されるためです。

j = 16/2*2;

プリコンパイラは展開に対して何も処理を行いません。展開されたマクロをそのままコードに配置します。置換テキストを括弧で囲んでいないため、メイン コードでもそれを行いません。成功する :

#define SQUARE(n) ((n)*(n))
于 2013-01-30T13:19:58.963 に答える
2

マクロの展開は次のようになります。

  j = 16/SQUARE(2);
  j = 16/2*2;

に等しい :j = (16/2)*2;手段j = 16;

と :

 j = 16/(SQUARE(2));
 j = 16/(2*2);

に等しい :j = 16/4;手段j = 4;

于 2013-01-30T13:19:26.073 に答える
1

最初の例は次のように評価されます。

16 / 2 * 2
(16 / 2) * 2
8 * 2
16

2番目の例は次のように評価されます。

16 / (2 * 2)
16 / 4
4

プリプロセッサステートメントに括弧を追加して、操作の順序を制御します。

#define SQUARE(n) ((n)*(n))

((n)*(n))の外括弧は、外部操作が実行される前にnが2乗されることを保証します。内側の括弧(n)は、次のようにSQUAREに式を渡す場合にnが正しく評価されることを保証します。

16 / SQUARE(2 * 2)
16 / ((2 * 2)*(2 * 2))
16 / (4 * 4)
16 / 16
1
于 2013-01-30T13:22:29.137 に答える
0
Its because Whenever macro name is used, it is replaced by the contents of the macro.its simple rule of working of macro.


Case 1 : result 16

        define SQUARE(n) n*n
        void main()
         {
            int j;      
            j =16/SQUARE(2);

          printf("\n j=%d",j);
          getch();
       }

its get expand as below


j =16/SQUARE(2); 

so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n

j = 16/2*2
j = (16/2)*2
j = 8*2
j =16



Case 2 : result 4



        define SQUARE(n) n*n

        void main()
       {
            int j;      
            j =16/(SQUARE(2));

          printf("\n j=%d",j);
          getch();
       }



its get expand as below


j =16/(SQUARE(2));

so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n

j = 16/(2*2)
j = 16/(4)
j = 4


Hope this will help
于 2013-01-30T15:44:34.313 に答える
0

あなたが得るでしょう

j =16/2*2; // (16 / 2) * 2 = 16
于 2013-01-30T13:20:16.500 に答える