How does this C code work?

2019-03-28 10:44发布

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)?

7条回答
我欲成王,谁敢阻挡
2楼-- · 2019-03-28 11:25

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.

查看更多
手持菜刀,她持情操
3楼-- · 2019-03-28 11:30

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

查看更多
ら.Afraid
4楼-- · 2019-03-28 11:35

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"

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-03-28 11:38
  #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

查看更多
干净又极端
6楼-- · 2019-03-28 11:44

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.

查看更多
男人必须洒脱
7楼-- · 2019-03-28 11:50

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.

查看更多
登录 后发表回答