【问题标题】:C preprocessor macro to create lookup table用于创建查找表的 C 预处理器宏
【发布时间】: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 的函数

我的问题是

  1. 使用#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 的十进制值。这是为什么呢?
  2. 如何使用宏自动执行此部分?注意:树枝的数量可以是非负整数,最多 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


【解决方案1】:

关闭“”? CHAR_1 包含您的字符 ascii 值。

【讨论】:

  • 这不起作用,因为预处理器输出将是 {.twig_id = A,... 使编译器认为 A 是一个变量,然后抛出一个错误,说 A 未声明。
  • 它有效!还有一些其他的问题。
     #define CREATE_TWIG(CHAR_1, CHAR_2) twig_t twig_##CHAR_1##CHAR_2 = {.twig_id = #CHAR_1[0], .leaf_function = &command_##CHAR_1##CHAR_2};
  • 不为我编译``` ../main/example_spp_acceptor_demo.c:140:16: 错误:初始化元素不是常量 CREATE_TWIG(A,X) ^ ```
  • 更改:void (*leaf_function)(void);在结构 twig_t 中。 typeof函数指针错误
  • 这是对上层 cmets 的注释,但如果您使用表 array_of_functions[26][26] 那么您可以编写链接器文件,在其中删除那些您不需要的元素。因此未保留未使用的内存。
猜你喜欢
  • 2020-02-09
  • 2016-07-29
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2012-11-16
  • 2016-12-14
  • 2011-03-26
相关资源
最近更新 更多