8

コードを実行する理由:

#define EXPONENT(num, exp) num ## e ## exp
EXPONENT(1,1)
EXPONENT(1,-1)
EXPONENT(1,+1)

前処理後、次のように変更されます。

1e1
1e- 1
1e+ 1

ではなく

1e1
1e-1
1e+1

? -1,+1 が 2 つのトークン (?) として解析されるためではないかと思います。しかし、その場合、後者の結果はどのように得られるのでしょうか?

4

3 に答える 3

4

-1おっしゃる通り、+1前処理トークンが 2 つあるため、最初のトークンのみが に貼り付けられますe

私のため、

#define EXPO(num, sign, ex) num ## e ## sign ## ex

EXPO(1,,1)
EXPO(1,-,1)
EXPO(1,+,1)

gcc-4.5.1 で動作しました。

于 2012-07-12T14:37:13.907 に答える
3

あなたが遭遇している問題は、未定義の動作と見なされると思います。連結に関するgcc 4.3.2ドキュメントごと:

ただし、一緒に有効なトークンを形成しない 2 つのトークンを一緒に貼り付けることはできません。たとえば、x と + をどちらの順序でも連結することはできません。試行すると、プリプロセッサは警告を発行し、2 つのトークンを発行します。トークン間に空白を入れるかどうかは未定義です。複雑なマクロで ## の不必要な使用を見つけるのはよくあることです。この警告が表示された場合は、単純に「##」を削除できる可能性があります。

同じ問題を示す SO に関するこの回答も参照してください。

編集:

これでうまくいきましたが、+ と - には 2 つのマクロが必要です。

#define E(X) 1e-##X
int main()
{
  double a = E(10); // expands to 1e-10
  printf("%e", a);
  return 0;
}
于 2012-07-12T14:35:11.007 に答える
-1
#include <stdio.h>
#include <stdlib.h>

#define EXPONENT(num, exp) atof(#num "e" #exp)

void main(){
    double x = EXPONENT(1,-1); 
    printf("%f", x);
}
于 2012-07-12T15:18:25.980 に答える