How does this C code work?

2019-03-28 10:56发布

问题:

What is 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]
  }

How does this program work?


The output is

12
f(1, 2)

now I understand how a##b & #a work. But why is the result different in the two cases (line 1 and line 2)?

回答1:

The ## concatenates two tokens together. It can only be used in the preprocessor.

f(1,2) becomes 1 ## 2 becomes 12.

The # operator by itself stringifies tokens: #a becomes "a". Therefore, g(f(1,2)) becomes "f(1,2)" when the preprocessor is done with it.

h(f(1,2)) is effectively #(1 ## 2) which becomes #12 which becomes "12" as the preprocessor runs over it.



回答2:

For questions like these (and also more "real-world" problems having to do with the preprocessor), I find it very helpful to actually read the code, after it has been preprocessed.

How to do this varies with the compiler, but with gcc, you would use this:

$ gcc -E test.c

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

So, you can see that the symbols have been both concatenated, and turned into a string.



回答3:

a##b will paste the code togather.

so f(1,2) will become 12



回答4:

The f(a,b) macro concatenates its arguments, g(a) turns its arguments to a string and h(a) is helper macro for g(a). I think it will output:

12
f(1,2)

The reason is that the h(a) macro causes its argument to be full expanded before passing it to g(a) while g(a) will take its arguments literally without expanding them first.



回答5:

a##b is the string contatenation of the literals a and b, so f(1,2) is "12"

#a is the string literal a, so g(3) is "3"



回答6:

## is the macro concatenation operator. So for example f(foo,bar) would be equivalent to foobar.



回答7:

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

So, ## combine 2 parts directly together, no matter what types they are... Give you a example.. printf("%d\n",f(1,2)); you get 12, that means here f(1,2) is 12 a integer.

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

here f(a,2) is label. it points to a label in your code context, if there is not int a2 = 100, you get compile errors. And #a turns whatever a is , into a string... And then h(a) g(a) It's very strange.. It looks that when you call h(a), it turns to g(a), and passes a into g(a), firstly, it interprets what a is. so, before you can g(a), a is transformed to f(a,b) = a##b = 12