如何在另一个数组中声明一个数组而不定义大小

时间:2020-12-30 15:10:40

标签: c

我想定义一个没有大小的数组,它也包含一个没有 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

是否有可能避免这些警告!

3 个答案:

答案 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]);
}
}
相关问题