点击这里给我发消息 点击这里给我发消息

C语言的静态映射声明的方法

添加时间:2013-12-7
    相关阅读: 设计 模板 C语言 维护
  前段时间,准备设计一个关于出错信息的表,每一个错误有一个唯一的ErrID,和对应的错误信息以及其他辅助信息。在C语言中,很自然的实现如下:
enum {
    ERR_ID_1,
    ERR_ID_2,
    ERR_ID_3,
    ERR_ID_4
} ErrID;

const char* errmsg[] = {
    \"This is Error 1 msg\", /*ERR_ID_1*/
    \"This is Error 2 msg\", /*ERR_ID_2*/
    \"This is Error 3 msg\", /*ERR_ID_3*/
    \"This is Error 4 msg\"  /*ERR_ID_4*/
};

int main() {
    printf(\"Error= %s\", errmsg[ERR_ID_1]);
    return 0;
}

这样带来的问题是很不容易维护,必须人为的确定每一个ErrID和它的errmsg相对应。希望能不增加任何时间或空间的开销的情况下,让实现更加的“美观”,更容易维护。自己第一时间能想到的,就是宏或者模板。
方法一
 
#define ERR_MSG(id, msg) const char* err_msg_##id = msg;
#define GET_MSG(id) (err_msg_##id)

ERR_MSG(ERR_ID_1, \"This is Error 1 msg\")
ERR_MSG(ERR_ID_2, \"This is Error 2 msg\")
ERR_MSG(ERR_ID_3, \"This is Error 3 msg\")
ERR_MSG(ERR_ID_4, \"This is Error 4 msg\")

int main() {
    printf(\"Error= %s\", GET_MSG(ERR_ID_1));
    return 0;
}

这个方法的好处在于连errmsg数组的空间都省略掉了。缺点就是
不能支持在运行时通过传入的ErrID来动态决定输出。 
不支持基于errmsg的遍历操作甚至不知道ErrID的个数。因为errmsg本来就不存在。
方法二
首先,另外建一个文件,比如err.txt,每行的格式如:
ERR_MSG(ERR_ID_1, \"This is Error 1 msg\")
ERR_MSG(ERR_ID_2, \"This is Error 2 msg\")
ERR_MSG(ERR_ID_3, \"This is Error 3 msg\")
ERR_MSG(ERR_ID_4, \"This is Error 4 msg\")
在主文件中:
#undef ERR_MSG
#define ERR_MSG(id, msg) id,
enum {
    #include \"err.txt\"
    MAX_ERR_NUMBER
} ERRID;

#undef ERR_MSG
#define ERR_MSG(id, msg) msg,
const char* errmsg[] = {
    #include \"err.txt\"
    \"\"
};
在最后加入一个无用的元素,用来避免某些编译器监测到最尾元素后有逗号时的警告。
当然,errmsg数组也不一定需要。比如,可以这样实现一个通过传入的ErrID返回相应errmsg的函数get_err_msg(): [Page]
#undef ERR_MSG
#define ERR_MSG(id, msg) case id: return msg; break;
const char* get_err_msg(ErrId eid) {
    switch (eid) {
        #include \"err.txt\"
    }
    return NULL; // Dummy。用来消除某些编译器的警告。
}
相关C语言的静态映射声明的方法

咨询热线:020-85648757 85648755 85648616 0755-27912581 客服:020-85648756 0755-27912581 业务传真:020-32579052
广州市网景网络科技有限公司 Copyright◎2003-2008 Veelink.com. All Rights Reserved.
广州商务地址:广东省广州市黄埔大道中203号(海景园区)海景花园C栋501室
= 深圳商务地址:深圳市宝源路华丰宝源大厦606
研发中心:广东广州市天河软件园海景园区 粤ICP备05103322号 工商注册