我有一个令牌列表,定义如下:

#define TOKENS ACC, STOP, RUN, BACK

这份 list 可能会发生变化. 我想根据该列表创建一个函数指针数组,方法类似于:

int (*callbacks[])(const char * arg) =
{
   some_macro_shenanigans(TOKENS)
};

some_macro_shenanigans(TOKENS)应该扩展到ACC_callback, STOP_callback, ...,以此类推.稍后,我想创建一个基于TOKENS的字符串数组,如下所示:

const char * const token_str[] = some_other_macro_shenanigans(TOKENS);

它将扩展为与以下内容相当的东西:

const char * const token_str[] = [ "ACC", "STOP", "RUN", "BACK" /* and others if present */ ];

这是可行的吗?

推荐答案

当然,使用x宏(正如 comments 所指向的那样):

#define TOKENS(DO) \
    DO(ACC) \
    DO(STOP) \
    DO(RUN) \
    DO(BACK) 

#define GEN_CALLBACK(ID) ID##_callback,
#define GEN_NAME(ID) #ID,

int (*callbacks[])(const char * arg) = { TOKENS(GEN_CALLBACK) };
const char * const token_str[] = [ TOKENS(GEN_NAME) ];

preprocesses to (godbolt link)

int (*callbacks[])(const char * arg) = { ACC_callback, STOP_callback, RUN_callback, BACK_callback, };
const char * const token_str[] = [ "ACC", "STOP", "RUN", "BACK", ];

C++相关问答推荐

C:scanf(%d&q;,...)输入只有一个减号

变量>;-1如何在C中准确求值?

struct 上的OpenMP缩减

在C++中通过空指针隐式访问常量变量的值

C中函数类型的前向声明

X64:并发写入布尔数组

S将C语言宏定义为自身的目的是什么?(在glibc标题中看到)

在每种If-Else情况下执行语句的最佳方式

关于scanf()和空格的问题

Go和C中的数据 struct 对齐差异

分配给静态变量和动态变量的位置之间有区别吗?

Leet代码运行时错误:代码不会在Leet代码上编译,而是在其他编译器中编译,如netbeans和在线编译器

分支预测和UB(未定义的行为)

execve 不给出which命令的输出

如何找出C中分配在堆上的数组的大小?

为什么写入关闭管道会返回成功

与 C 相比,C++ 中无副作用的无限循环的好处是 UB?

`void foo(int a[static 0]);` 有效吗?

如何确定 C 程序中的可用堆内存

求数组元素的lcm的C程序