我想定义一个没有大小的数组,它也包含一个没有 siez 的数组。
在函数之后:
#include <stdio.h>
typedef struct dm_key_reg {
char *obj;
char **ukey;
}DMKEYREG;
DMKEYREG tab_reg_key[]={
{"Device_SS", {"SerialSS", "SSS"}},
{"Device__AP", {"SerialAP", "III"}},
{"Device___EP", { "SerialEP", "EEE", "CCC"}},
{0}
};
int main(void)
{
DMKEYREG *tab_key = tab_reg_key;
for (; tab_key->obj; tab_key++) {
printf("obj= %s\n",tab_key->obj);
}
}
但是在构建此示例时,我收到以下警告:
test.c:9:1: warning: braces around scalar initializer
{"Device_SS", {"SerialSS", "SSS"}},
^
test.c:9:1: note: (near initialization for ‘tab_reg_key[0].ukey’)
test.c:9:16: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
{"Device_SS", {"SerialSS", "SSS"}},
^
test.c:9:16: note: (near initialization for ‘tab_reg_key[0].ukey’)
test.c:9:28: warning: excess elements in scalar initializer
{"Device_SS", {"SerialSS", "SSS"}},
^
test.c:9:28: note: (near initialization for ‘tab_reg_key[0].ukey’)
test.c:10:1: warning: braces around scalar initializer
{"Device__AP", {"SerialAP", "III"}},
^
test.c:10:1: note: (near initialization for ‘tab_reg_key[1].ukey’)
test.c:10:17: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
{"Device__AP", {"SerialAP", "III"}},
^
test.c:10:17: note: (near initialization for ‘tab_reg_key[1].ukey’)
test.c:10:29: warning: excess elements in scalar initializer
{"Device__AP", {"SerialAP", "III"}},
^
test.c:10:29: note: (near initialization for ‘tab_reg_key[1].ukey’)
test.c:11:1: warning: braces around scalar initializer
{"Device___EP", { "SerialEP", "EEE", "CCC"}},
^
test.c:11:1: note: (near initialization for ‘tab_reg_key[2].ukey’)
test.c:11:19: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
{"Device___EP", { "SerialEP", "EEE", "CCC"}},
^
test.c:11:19: note: (near initialization for ‘tab_reg_key[2].ukey’)
test.c:11:31: warning: excess elements in scalar initializer
{"Device___EP", { "SerialEP", "EEE", "CCC"}},
^
test.c:11:31: note: (near initialization for ‘tab_reg_key[2].ukey’)
test.c:11:38: warning: excess elements in scalar initializer
{"Device___EP", { "SerialEP", "EEE", "CCC"}},
^
test.c:11:38: note: (near initialization for ‘tab_reg_key[2].ukey’)
zribi@zribi-ThinkPad-E480:~/Bureau$ ./test
obj= Device_SS
obj= Device__AP
obj= Device___EP
是否有可能避免这些警告!
答案 0 :(得分:0)
您收到警告是因为您试图将 char **
初始化为一个数组。这会产生另一个警告,因为您正在尝试使用 char **
初始化 char *
。
您可以通过创建类型为 char *
数组的复合文字来解决这个问题,即 char *[]
,它将衰减为所需的 char **
类型。您还应该将类型更改为 const char **
,因为您有无法更改的字符串文字。
typedef struct dm_key_reg {
const char *obj;
const char **ukey;
}DMKEYREG;
DMKEYREG tab_reg_key[]={
{"Device_SS", (const char *[]){"SerialSS", "SSS", NULL}},
{"Device__AP", (const char *[]){"SerialAP", "III", NULL}},
{"Device___EP", (const char *[]){ "SerialEP", "EEE", "CCC", NULL}},
{0}
};
另请注意,您需要在每个列表的末尾添加一个 NULL 分隔符,以便您知道何时到达末尾。
答案 1 :(得分:0)
char **ukey
不是数组,也不是指向数组的指针。然而,它可以是指向指针数组中第一个元素的指针。这意味着分配给 ukey
的每个初始化器都需要是一个指针数组(指向 char)。你可以通过将这样的指针数组声明为复合文字来实现,在这种情况下
(const char*[]){ /* data here */ }
。
其次,所有字符串文字 ("this stuff"
) 都是只读的。因此,您应该总是 const
限定指向字符串文字的指针,否则有人可能会不小心写入访问它们,从而调用未定义的行为。 (如果您需要数据具有读/写访问权限,那么情况就完全不同了。)
在这种情况下,这意味着结构的两个对象都必须是 const 限定的。然后你也可以将结构对象也设为 const。
更正后的安全版本可能如下所示:
#include <stdio.h>
typedef struct dm_key_reg
{
const char* obj;
const char** ukey;
}DMKEYREG;
const DMKEYREG tab_reg_key[] =
{
{ .obj = "Device_SS",
.ukey = (const char*[]){"SerialSS", "SSS"} },
{ .obj = "Device__AP",
.ukey = (const char*[]){"SerialAP", "III"} },
{ .obj = "Device___EP",
.ukey = (const char*[]){"SerialEP", "EEE", "CCC"}},
{0}
};
int main(void)
{
const DMKEYREG* tab_key = tab_reg_key;
for (; tab_key->obj!=NULL; tab_key++)
{
printf("obj= %s\n",tab_key->obj);
}
}
还要考虑在每个字符串列表的末尾使用 NULL 标记值。即:
(const char*[]){"SerialSS", "SSS", NULL}
否则您无法知道该数组中存储了多少个字符串,因为您没有保存数组大小。
答案 2 :(得分:-1)
这里是解决方案之后:
#include <stdio.h>
#define LIST_KEY (const char *[])
typedef struct dm_key_reg {
char *obj;
const char **ukey;
}DMKEYREG;
DMKEYREG tab_reg_key[]={
{"Device_SS", LIST_KEY{"SerialSS", "SSS"}},
{"Device__AP", LIST_KEY{"SerialAP", "III"}},
{"Device___EP", LIST_KEY{ "SerialEP", "EEE", "CCC"}},
{0}
};
int main(void)
{
DMKEYREG *tab_key = tab_reg_key;
for (; tab_key->obj; tab_key++) {
printf("obj= %s\n",tab_key->obj);
printf("ukey0= %s\n",tab_key->ukey[0]);
printf("ukey1= %s\n",tab_key->ukey[1]);
}
}