【发布时间】:2020-03-14 02:12:56
【问题描述】:
我有一个查找表,它链接了我所有的“两个字符命令”,例如AA、AB、SS,按字母顺序排列它们对应的函数地址的第一个char。
command_list 中的行,即分支,对应于它们的 ascii 值减去 'A'
IE。
command_list[0] 是所有“A”命令
command_list[1] 是所有“B”命令。
此外,第二个字符在“分支”下分配了一个“树枝”
例如如果命令 AA 分配给 twig 0....
command "AA" 变成 command_list['A' -'A']->twig[0] 变成 command_list[0]->twig[0] 然后我可以调用地址 command_list[0]->twig[0]->leaf_function 的函数
我的问题是
- 使用
#define CREATE_TWIG(CHAR_1, CHAR_2) twig_t twig_##CHAR_1##CHAR_2 = {.twig_id = 'CHAR_1', .leaf_function = &command_##CHAR_1##CHAR_2};我可以创建一个twig,但是.twig_id被搞砸了并且总是被分配(int) 1 而不是CHAR_1的十进制值。这是为什么呢? - 如何使用宏自动执行此部分?注意:树枝的数量可以是非负整数,最多 26 个,即 A 到 Z
twig_t * A_twigs[2] = {&twig_AD, &twig_AS};
branch_t A_branch = {.branch_id = 'A', .num_twigs = 2, .twigs = A_twigs};
tree command_list[1] = {&A_branch};
其余的代码/typedefs/structs
typedef struct{
uint8_t twig_id;
void * leaf_function;
}twig_t;
typedef struct{
uint8_t branch_id;
uint8_t num_twigs;
twig_t **twigs;
}branch_t;
typedef branch_t* tree;
void command_AD(void);
void command_AS(void);
#define CREATE_TWIG(CHAR_1, CHAR_2) twig_t twig_##CHAR_1##CHAR_2 = {.twig_id = 'CHAR_1', .leaf_function = &command_##CHAR_1##CHAR_2};
CREATE_TWIG(A,S)
twig_t twig_AD = {.twig_id = 'D', .leaf_function = &command_AD};
twig_t * A_twigs[2] = {&twig_AD, &twig_AS};
branch_t A_branch = {.branch_id = 'A', .num_twigs = 2, .twigs = A_twigs};
tree command_list[1] = {&A_branch};
【问题讨论】:
-
预处理器无法从
D创建像'D'这样的字符常量。 (但 Microsoft 编译器有非标准的 "Charizing operator"。)宏的替代方法是使用单独的程序创建表,该程序编写包含文件并且可以作为构建过程的一部分。 -
不是一个直接的答案:因为在任何情况下都必须计算两个索引,所以只有一个
array_of_functions[26][26]会不会更容易?您需要将 ID 存储在结构中吗? -
@HelmutWollmersdorfer 理想情况下,我想让我的生活变得轻松,但这是针对嵌入式系统的,即低 RAM、低处理能力,因此决定使用查找表。原始代码有一个循环,每次都用完整的命令列表检查每个传入的命令,返回一个代码,然后运行一个代码列表来执行一个子例程……效率不高。查找表对我来说似乎更有效,但我对想法持开放态度。
-
@hhonab1 一个 26 x 26 = 676 个仅指针条目的数组。如果没有叶函数,则让该字段为零(如果没有指针为零的叶函数)。尝试估计两种变体的空间和运行时间并进行比较。这取决于存在多少个函数。
标签: c macros preprocessor