欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++宏定义中#和##的用法

程序员文章站 2024-03-22 10:20:23
...

前段时间很到了宏定义中的新知识:#与##,感觉打开了新天地的大门。
首先来介绍一下这两种功能:

#
#的用法是负责将其后面的东西转化为字符串,比如:

#define TO_STRING(str) #str

int main(){
    cout << TO_STRING(this is a string) << endl;
    return 0;
}


这段代码中,TO_STRING宏就会将括号中的内容转化为字符串,生成"this is a string",然后由cout输出。

##
##是连接符,将前后两个东西连接成一个词。比如:

#define IntVar(i) int_##i

int main(){
    int int_1 = 1, int_2 = 2;
    cout << IntVar(1) << ", " << IntVar(2) << endl;
    return 0;
}


这段代码中IntVar(1)就会将前面的int_与参数1连接起来,成为int_1,然后由cout输出int_1变量对应的值1。对于IntVar(2)同理。

最开始我一看,emmmmmm,高级啊!可以生成新的词汇!因为我最开始想做的是,如果有很多int变量,他们基本模式都一样,那我是不是可以用一个for循环来直接生成?比如:

#define create_int(i) int int_##i = i
#define print_int(i) cout << int_##i << endl

int main(){
    for(int i = 1; i <= 3; ++i) create_int(i);
    for(int i = 1; i <= 3; ++i) print_int(i);
}


这样。当然,我很快发现我想多了。我犯了一个很低级的错误。宏定义是在预编译的时候就进行了展开,i的值则是在运行时才确定下来的,想想也应该知道不可能达到我预想中的效果。这样做只会生成int_i变量,而不是int_1、int_2之类的。

那么##的正确打开方式是什么呢?其实它做的只是帮我们省去不变的部分,可变的部分仍然需要我们自己去完成。对于上面这个小小的示例用处可能不太明显,我们换一个:

#define TEST_CASE_1 "This is a super super super super long string for test to process"
#define TEST_CASE_2 "This is another super super super super long string for test to process"
#define TEST_CASE_3 "This is again another super super super super long string for test to process"

#define process_data(i) \
string temp = TEST_CASE_##i;\
do_something

int main(){
    process_data(1);
    process_data(2);
    process_data(3);
}


比如说如上代码,do_something可能有很多行,而你重复的部分又难以做成循环,因为变量由于某种原因难以做成数组。这个时候用到##就会很方便啦~

另外,##还可以用来省略前缀。比如:

#define func(ptr, type) _func(ptr, T_##type)

enum TYPE{
    T_INT,
    T_FLOAT,
    T_CHAR,
}
void _func(void* ptr, TYPE type){
    switch(type){
    case T_INT:
        cout << *((int*)ptr) << endl; break;
    case T_FLOAT:
        cout << *((float*)ptr) << endl; break;
    case T_CHAR:
        cout << *((char*)ptr) << endl; break;
    default:
        break;
    }
}
int main(){
    int x = 1, *ptr = &x;
    func(ptr, INT);
}


这样就可以省去前缀,看起来更方便。

当然还有更多的用法,我就不一一列举啦。