奇怪的是在C ++预处理器中定义

时间:2011-08-17 11:03:52

标签: visual-c++ concatenation c-preprocessor stringification

我遇到过这个

#define DsHook(a,b,c) if (!c##_) {  INT_PTR* p=b+*(INT_PTR**)a;  VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c##_=*p;  VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no);  *p=(INT_PTR)c; }

除了“c ## _”这个词之外,一切都很清楚,这是什么意思?

6 个答案:

答案 0 :(得分:4)

这意味着要“粘合”在一起,因此c_会“粘在一起”形成c_。这种粘合发生在宏中的参数替换之后。看我的例子:

#define glue(a,b) a##_##b

const char *hello_world = "Hello, World!";

int main(int arg, char *argv[]) {
    printf("%s\n", glue(hello,world)); // prints Hello, World!
    return 0;
}

答案 1 :(得分:3)

它被称为a token-pasting operator。例如:

// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;

int main()
{
   paster(9);
}

<强>输出

token9 = 9

答案 2 :(得分:2)

这是将下划线附加到以c传递的名称的串联。所以当你使用

DsHook(a,b,Something)

该部分变为

if (!Something_) 

答案 3 :(得分:2)

在预处理器之后,您的宏将扩展为:

if (!c_) {  INT_PTR* p=b+*(INT_PTR**)a;  VirtualProtect(&c_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c_=*p;  VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no);  *p=(INT_PTR)c; }

##指令将作为宏参数传递的c的值连接到_

答案 4 :(得分:1)

简单的一个:

#define Check(a) if(c##x == 0) { }

在致电网站:

int varx; // Note the x
Check(var);

将扩展为:

if(varx == 0) { }

答案 5 :(得分:1)

它被称为Token Concatenation,它用于在预处理期间连接令牌 例如,以下代码将打印出c,c_,c_spam值的值:

#include<stdio.h>

#define DsHook(a,b,c) if (!c##_) \
    {printf("c=%d c_ = %d and c_spam = %d\n",\
    c, c##_,c##_spam);}

int main(){
    int a,b,c=3;
    int c_ = 0, c_spam = 4;

    DsHook(a,b,c);

    return 0;
}

输出:

c=3 c_ = 0 and c_spam = 4