c中的查找表
Posted
技术标签:
【中文标题】c中的查找表【英文标题】:lookup table in c 【发布时间】:2011-04-21 23:46:15 【问题描述】:我正在用 C 创建一个查找表 当我定义这个时:
typedef struct
char* action;
char* message;
lookuptab;
lookuptab tab[] =
"aa","bb",
"cc","dd"
;
它编译没有错误,但是当我做这样的事情时:
typedef struct
char* action;
char* message[];
lookuptab;
lookuptab tab[] =
"aaa", "bbbb", "ccc",
"cc", "dd", "eeeee"
;
我收到以下错误:
错误:灵活初始化 嵌套上下文中的数组成员
错误:(接近初始化为 ‘tab[0].message’)
如何初始化第二个示例中的选项卡数组? 注意:我知道 tab 数组中的所有值。
更新:消息的大小可能不同,例如
typedef struct
char* action;
char* message[];
lookuptab;
lookuptab tab[] =
"aaa", "bbbb", "ccc", "dd",
"cc", "dd", "eeeee"
;
非常感谢。
最好的问候, 维克多
【问题讨论】:
【参考方案1】:您不能在(结构的)数组中使用包含灵活数组成员的结构。参见 C99 标准 §6.7.2.1/2:
结构或联合不应包含不完整或函数类型的成员(因此, 结构不应包含自身的实例,但可以包含指向实例的指针 本身),除了具有多个命名成员的结构的最后一个成员 可能有不完整的数组类型;这样的结构(以及任何包含,可能 递归地,作为这种结构的成员)不应是结构的成员或 数组的元素。
因此,请改用char **
(并担心您如何知道有多少条目):
typedef struct
const char *action;
const char * const *message;
lookuptab;
static const lookuptab tab[] =
"aaa", (const char * const []) "bbbb", "ccc" ,
"cc", (const char * const []) "dd", "eeeee"
;
这使用 C99 构造(第 6.5.2.5 节复合文字) - 如果您不使用 C99 编译器,请注意。
【讨论】:
我只是打开我的旧 C 书来理解这个结构;)(Java 正在扼杀我的工程技能......)【参考方案2】:我认为您必须指定数组大小才能在另一个数组中使用该结构:
typedef struct
char* action;
char* message[2];
lookuptab;
【讨论】:
要么这样,要么吞下苦果并使用多行代码进行初始化;) 您好,谢谢,您的选择有效,但消息的大小也可能不同,我刚刚更新了我的问题以反映这一点。对不起。 顺便说一句,对消息使用 fix-max-size 也不太喜欢我。 @Victor:在这种情况下,您必须将message
的大小设置为可能的最大大小。或者只是使用指针手动管理内存,如另一个答案中所建议的那样。【参考方案3】:
您需要在结构定义中为message
数组成员指定一个大小:
#define N ... // maximum number of elements in message array
typedef struct
char *action;
char *message[N];
lookuptab;
lookuptab tab[] =
"aa", "bb", "cc",
"dd", "ee", "ff",
...
;
在这种情况下,N 必须至少为 2。
如果您希望lookuptab
结构的每个实例在message
数组中具有不同数量的元素,那么您必须分别分配每个message
数组,这意味着您将无法使用静态初始化器:
typedef struct
char *action;
char **messages;
lookuptab;
lookuptab *newEntry(const char *action, size_t numMessages, ...)
lookuptab *entry = malloc(sizeof *entry);
if (entry)
entry->action = malloc(strlen(action) + 1);
if (entry->action)
strcpy(entry->action, action);
if (numMessages > 0)
entry->messages = malloc(sizeof *entry->messages * numMessages);
if (entry->messages)
size_t i;
va_list ap;
va_start(ap, numMessages);
for (i = 0; i < numMessages; i++)
char *nextMessage = va_arg(ap, char *);
entry->messages[i] = malloc(strlen(nextMessage) + 1);
if (entry->messages[i])
strcpy(entry->messages[i], nextMessage);
return entry;
int main(void)
lookuptab *tab[ENTRIES]; // for some number of ENTRIES
tab[0] = newEntry("AA", 2, "BB", "CC");
tab[1] = newEntry("DD", 3, "EE", "FF", "GG");
tab[2] = newEntry("HH", 0);
...
您可以使用哨兵来代替显式传递消息的数量:
tab[0] = newEntry("AA", "BB", "CC", NULL);
但是您要么必须循环遍历所有参数两次(首先获取分配messages
数组的编号,然后复制每条消息),或者您必须为每条消息分配realloc()
数组,如:
size_t numMessages = 0;
...
char *nextMessage
while ((nextMessage = va_arg(ap, char *)) != NULL)
char **tmp = realloc(entry->messages, sizeof *entry->messages, numMessages+1);
if (tmp)
entry->messages = tmp;
entry->messages[numMessages] = malloc(strlen(nextMessage) + 1);
strcpy(entry->messages[numMessages], nextMessage);
numMessages++;
【讨论】:
【参考方案4】:typedef struct
char* action;
char* message[];
lookuptab;
lookuptab
是不完整的类型。您不能创建该类型的对象。要么为消息数组提供一个确定的大小
typedef struct
char* action;
char* message[42];
lookuptab_definite_size;
或使用指针并“手动”管理内存
typedef struct
char* action;
char** message;
lookuptab_pointers_all_around;
您可以使用灵活的数组成员(所有元素都将具有相同的大小),但工作量很大:-)
#include <stdlib.h>
typedef struct
char* action;
char* message[];
lookuptab;
int main(void)
lookuptab *tab;
tab = malloc(sizeof *tab + 42 * sizeof *tab->message);
/* tab = malloc(elems * (sizeof *tab + 42 * sizeof *tab->message)); */
/* tab[0] ... tab[elems-1] all have the same size */
if (tab)
tab->action = NULL;
tab->message[0] = NULL;
tab->message[1] = NULL;
/* ... */
tab->message[41] = NULL;
free(tab);
return 0;
【讨论】:
您不能像评论建议的那样分配灵活数组成员结构的数组 - 编译器无法知道tab[1]
应该从哪里开始。
在我的代码中它说所有数组元素都具有相同的大小,我编辑了注释以使其更加可见。感谢您指出这一点。以上是关于c中的查找表的主要内容,如果未能解决你的问题,请参考以下文章