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():

#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。用来消除某些编译器的警告。}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索this
, define
, error
, err
, msg
, is
, 一个
ERR:
c语言函数声明、c语言声明数组、c语言函数声明和定义、c语言声明、c语言函数声明格式,以便于您获取更多的相关知识。

时间: 2024-09-20 17:00:14

C语言的静态映射声明的相关文章

C语言的静态库与共享库

1库的概念 2静态库 2-1 静态库的概念 2-2 静态库的创建 2-2-1 静态库创建的命令 2-2-2 静态库创建的准备工作 2-2-3 创建静态库的例子 2-3 静态库的使用 2-3-1 静态库使用的命令 2-3-2 静态库使用的例子 3共享库动态链接库 3-1 共享库的概念 3-2 共享库的创建 3-2-1 共享库的创建命令 3-2-2 共享库的创建例子 3-3 共享库的使用 3-3-1 共享库的使用命令 3-3-2 共享库的使用例子 4不使用库的方法 1.库的概念 函数库是由系统建立的

Go语言中的变量声明和赋值的方法

  Go语言中的变量声明和赋值的方法           这篇文章主要介绍了Go语言中的变量声明和赋值的方法,十分的细致全面,有需要的小伙伴可以参考下. 1.变量声明和赋值语法 Go语言中的变量声明使用关键字var,例如 代码如下: var name string //声明变量 name = "tom" //给变量赋值 这边var是定义变量的关键字,name是变量名称,string是变量类型,=是赋值符号,tom是值.上面的程序分两步,第一步声明变量,第二步给变量赋值.也可以将两步合到

c语言int与_int64声明不同导致输出#info是什么意思?

问题描述 c语言int与_int64声明不同导致输出#info是什么意思? #include int main() { _int64 m,n; double sum=0; scanf("%I64d %I64d",&n,&m); for(;n<=m;n++) { sum+=1.0/(n*n); } printf("%.5lf",sum); return 0; } 代码如上,请问各位大神 为什么把_int64 改为int后,当n=65530 m=6

Go语言中的变量声明和赋值_Golang

1.变量声明和赋值语法 Go语言中的变量声明使用关键字var,例如 复制代码 代码如下: var name string //声明变量 name = "tom" //给变量赋值 这边var是定义变量的关键字,name是变量名称,string是变量类型,=是赋值符号,tom是值.上面的程序分两步,第一步声明变量,第二步给变量赋值.也可以将两步合到一起. 复制代码 代码如下: var name string = "tom" 如果在声明时同时赋值,可以省略变量类型,Go语

C语言中函数的声明、定义及使用的入门教程_C 语言

对函数的"定义"和"声明"不是一回事.函数的定义是指对函数功能的确立,包括指定函数名,函数值类型.形参及其类型以及函数体等,它是一个完整的.独立的函数单位.而函数的声明的作用则是把函数的名字,函数类型以及形参的类型.个数和顺序通知编译系统,以便在调用该函数时进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致),它不包括函数体.--谭浩强 ,<C程序设计>(第四版),清华大学出版社,2010年6月,p182 这段论述包含了许多概念性错误,这

浅析Go语言编程当中映射和方法的基本使用_Golang

映射Go编程提供的一个重要的数据类型就是映射,唯一映射一个键到一个值.一个键要使用在以后检索值的对象.给定的键和值,可以在一个Map对象存储的值.值存储后,您可以使用它的键检索. 定义映射 必须使用make函数来创建一个映射. 复制代码 代码如下: /* declare a variable, by default map will be nil*/ var map_variable map[key_data_type]value_data_type /* define the map as n

Hibernate Core 4.0.0.Alpha1发布 Java语言对象关系映射解决方案

Hibernate是一种Java语言下的对象关系映射解决方案.它是使用GNU宽通用公共许可证发行的自由.开源的软件.它为面向对象的领域模型到传统的关系型数据库的映射,提供了一个使用方便的框架.Hibernate也是目前Java开发中最为流行的数据库持久层框架,现已归JBOSS所有. 它的设计目标是将软件http://www.aliyun.com/zixun/aggregation/7155.html">开发人员从大量相同的数据持久层相关编程工作中解放出来.无论是从设计草案还是从一个遗留数据

对C语言编程标准以及声明的基本理解_C 语言

c语言标准1978年,丹尼斯·里奇(Dennis Ritchie)和Brian Kernighan合作出版了<C程序设计语言>的第一版.书中介绍的C语言标准也被C语言程序设计师称作"K&R C",第二版的书中也包含了一些ANSI C的标准.K&R C主要介绍了以下特色: 结构(struct)类型 长整数(long int)类型 无符号整数(unsigned int)类型 把运算符=+和=-改为+=和-=.因为=+和=-会使得编译器不知道用户要处理i = +1

Go程序设计语言2.2 声明

2.2 声明 声明给一个程序实体命名,并且设定其部分或全部属性.有4个主要的声明:变量(var).常量(const).类型(type)和函数(func).本章讨论变量和类型,常量放在第3章讨论,函数放在第5章讨论. Go程序存储在一个或多个以.go为后缀的文件里.每一个文件以package声明开头,表明文件属于哪个包.package声明后面是import声明,然后是包级别的类型.变量.常量.函数的声明,不区分顺序.例如,下面的程序声明一个常量.一个函数和一对变量:   常量boilingF是一个