代码之家  ›  专栏  ›  技术社区  ›  jheddings

从C预处理器获取“编号”配置选项的最佳方法是什么?

  •  0
  • jheddings  · 技术社区  · 15 年前

    我们有一个库,可以访问设备上的按钮。这些按钮被枚举到系统的其余部分,如“电源按钮”等。这样,其他应用程序就不必担心“电源按钮”是如何实现的。

    #define BUTTON_COUNT 2
    #define BUTTON_0_NAME "power"
    #define BUTTON_1_NAME "reset"
    #define BUTTON_2_NAME NULL
    

    问题是,在某个时刻,我想获取按钮1的名称 get_button_name(int index)

    const char* get_button_name(int index) {
        switch (index) {
            case 0: return BUTTON_0_NAME;
            case 1: return BUTTON_1_NAME;
            case 2: return BUTTON_2_NAME;
        }
        return NULL;
    }
    

    问题是,许多设备共享此代码,因此支持的按钮数量将继续增加。这意味着更改此功能以及所有引入此功能的设备必须添加 #define 是为新按钮准备的。

    我真正喜欢的(尽管我不认为使用预处理器是可能的)是:

    const char* get_button_name(int index) {
        if (index < BUTTON_COUNT) {
            return BUTTON_ ## index ## _NAME;
        }
        return NULL;
    }
    

    5 回复  |  直到 8 年前
        1
  •  1
  •   Radu094    15 年前

    您需要找到一种方法将所有这些名称移动到某种数组中(lookup codegen、T4等) 然后做一个简单的查找

        2
  •  5
  •   sbi    15 年前

    只需要一个数组怎么样?

     const char *buttons[] = {
       "power",
       "reset"};
    
     const char* get_button_name(int index) {
         if (index < sizeof(buttons)/sizeof(buttons[0])) {
             return buttons[index];
         }
         return NULL;
     }
    
        3
  •  1
  •   Jerry Coffin    15 年前

    char const *names[] = {"power", "reset"};
    #define elements(array) (sizeof(array)/sizeof(array[0]))
    
    char const *get_button_name(size_t index) { 
        if (index < elements(names))
           return names[index];
        return NULL;
    }
    
        4
  •  0
  •   AShelly    15 年前

    您可以更改配置指令吗?或文本处理为以下形式:

    按钮h:

    #define MAKEBUTTONS() const char* gButtonNames[\
    "power",\
    "reset",\
    "macroize",\
    ]
    
    extern const char* gButtonNames[];
    #define GET_BUTTON_NAME(n) gButtonNames[n]
    

    那么只有一个源文件应该包含 MAKEBUTTONS(); 在全局范围内,任何客户端代码都可以调用 GET_BUTTON_NAME() 而不是函数。

        5
  •  0
  •   mjh2007    15 年前

    我会使用数组。如果将数组定义为extern,则可以在与get_button_name()函数分离的外部模块中声明它。例如:

    
    extern char const *names[] = {"power", "reset", "etc."};
    
    

    #define num_names 3

    char const *get_button_name(int index){ if(index < num_names) return names[index]; return NULL; }