6

a##b&とは#a

  #define f(a,b) a##b
  #define g(a)   #a
  #define h(a) g(a)

  main()
  {
          printf("%s\n",h(f(1,2)));  //how should I interpret this?? [line 1]
          printf("%s\n",g(f(1,2)));  //and this? [line 2]
  }

このプログラムはどのように機能しますか?


出力は

12
f(1, 2)

今、私は方法a##b#a働きを理解しています。しかし、2つのケース(1行目と2行目)で結果が異なるのはなぜですか?

4

7 に答える 7

19

##は、2つのトークンを連結します。プリプロセッサでのみ使用できます。

f(1,2)になり1 ## 2ます12

#演算子自体がトークンを文字列化#aします:になり"a"ます。したがって、プリプロセッサがそれで行われるときになりますg(f(1,2))"f(1,2)"

h(f(1,2))効果的には、プリプロセッサがその上を実行するときにどちらになる#(1 ## 2)かです。#12"12"

于 2009-11-06T09:05:55.373 に答える
5

このような質問(およびプリプロセッサに関係するより「現実的な」問題)については、前処理された後に実際にコードを読むことが非常に役立つと思います。

これを行う方法はコンパイラによって異なりますが、gccでは次のように使用します。

$ gcc -E test.c

(snip)
main()
{
        printf("%s\n","12");
        printf("%s\n","f(1,2)");
}

したがって、シンボルが連結され、文字列に変換されていることがわかります。

于 2009-11-06T09:07:30.300 に答える
4

a##bはコードを一緒に貼り付けます。

したがって、f(1,2)は12になります

于 2009-11-06T09:04:40.747 に答える
3

f(a、b)マクロは引数を連結し、g(a)は引数を文字列に変換し、h(a)はg(a)のヘルパーマクロです。私はそれが出力すると思います:

12
f(1,2)

その理由は、h(a)マクロは引数をg(a)に渡す前に完全に展開されるのに対し、g(a)は最初に引数を展開せずに文字通り引数を取るためです。

于 2009-11-06T09:06:38.460 に答える
0

a ## bは、リテラルaとbの文字列の連結であるため、f(1,2)は「12」です。

#aは文字列リテラルaであるため、g(3)は「3」です。

于 2009-11-06T09:06:14.310 に答える
0

##はマクロ連結演算子です。したがって、たとえば、f(foo,bar)と同等になりfoobarます。

于 2009-11-06T09:07:14.907 に答える
0
  #define f(a、b)a ## b
  #define g(a)#a
  #define h(a)g(a)

したがって、##は、タイプに関係なく、2つの部分を直接結合します...例を挙げてください。12 printf("%d\n",f(1,2));が得られます。つまり、ここでf(1,2)は12の整数です。

    int a2 = 100;
    printf( "%d \ n"、f(a、2));

ここでf(a、2)はラベルです。コードコンテキスト内のラベルを指します。ラベルがない場合はint a2 = 100、コンパイルエラーが発生します。そして#a、aが何であれ、文字列に変換します...そしてそれはh(a) g(a) 非常に奇妙です..h(a)を呼び出すと、g(a)に変換され、aをg(a)に渡します。 aが何であるかを解釈します。したがって、g(a)を実行する前に、aはf(a、b)= a ## b=12に変換されます。

于 2009-11-06T09:39:17.503 に答える