如何初始化一个长度可变的无符号字符数组?

5

我看了一遍这个链接(如何初始化一个无符号字符数组?),但它并没有完全回答我的问题。

我知道我可以像这样创建一个字符串数组:

const char *str[] =
{
  "first",
  "second",
  "third",
  "fourth"
};

如果我想要写()这些内容,可以使用:write(fd, str[3], sizeof(str[3]));

但是如果我需要一个长度可变的无符号字符数组怎么办?我尝试了这个方法:

const unsigned char *cmd[] =
{
  {0xfe, 0x58},
  {0xfe, 0x51},
  {0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23},
  {0xfe, 0x3d, 0x02, 0x0f}
};

我得到了像下面这样的gcc编译警告: * "标量初始化器周围有大括号" * "初始化会将整数转换为指针"


1
你必须为子数组引入名称,否则无法完成该操作。另外,你的代码有漏洞:write(fd, str[3], strlen(str[3]));。应该使用 strlen 而不是 sizeof。对指针使用 sizeof 只会返回指针本身的大小,而不是它所指向的数据的大小。 - john
1
不存在长度可变的数组。你的 str 是指针数组,而非长度可变的数组。使用字符串字面量初始化指针是可以的。没有数组字面量,也不能使用大括号列表来初始化指针。 - n. m.
好的,明白了。我理解并同意这里的评论。谢谢! - Rich G.
术语说明:在C语言中,“可变长度数组”(Variable Length Array)也称为VLA,具有非常特定的含义:它是一个在运行时确定长度的数组(即变量或函数参数)。标准C++不支持VLAs。此外,整个功能有些问题,在使用C语言之前请仔细阅读相关资料(在大多数情况下,您应该决定实际上不想使用它)。 - hyde
我知道这在多年(几十年)前的Borland Turbo C++ v3.0中可行。请参考此答案,看起来GCC没有自己将其转换为char[],需要一些帮助:https://dev59.com/bXDXa4cB1Zd3GeqP8htQ#15619960 - KJ7LNW
3个回答

6

这是一种方式

const unsigned char cmd1[] = {0xfe, 0x58};
const unsigned char cmd2[] = {0xfe, 0x51};
const unsigned char cmd3[] = {0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23};
const unsigned char cmd4[] = {0xfe, 0x3d, 0x02, 0x0f};

const unsigned char *cmd[] =
{
  cmd1,
  cmd2,
  cmd3,
  cmd4
};

你能解释一下为什么子数组需要命名吗? - dchhetri
n.m.在上面的评论中解释了它。 - john

1

当使用多维数组时,必须指定最后一个维度的大小,以便编译器计算正确的地址算术。您的cmd指针数组有两个维度。第二个维度最多可以包含6个元素,因此:

const unsigned char cmd[][6] =
{
      {0xfe, 0x58},
      {0xfe, 0x51},
      {0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23},
      {0xfe, 0x3d, 0x02, 0x0f}
};

根据 ANSI C 标准: 如果初始化一个未知大小的数组,则其大小将由具有显式初始化程序的最大索引元素确定。在初始化列表结束时,该数组不再具有不完整类型。

ANSI C 草案标准 C11


1
这对我有用(可以使用clang和gcc编译):
const unsigned char *cmd[] =
{
    (unsigned char[]){0xfe, 0x58},
    (unsigned char[]){0xfe, 0x51},
    (unsigned char[]){0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23},
    (unsigned char[]){0xfe, 0x3d, 0x02, 0x0f}
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接