首页 文章

C结构中的柔性阵列构件

提问于
浏览
5

引自C-std部分6.7.2.1,

struct s { int n; double d[]; };

这是一个有效的结构声明 . 我正在寻找这种语法的一些实际用途 . 确切地说,这个构造如何比保持double *作为第二个元素更强或更弱?或者这是“你可以做多种方式”的另一种情况吗?

Arpan

4 回答

  • 10

    主要优点是灵活的数组成员允许您为数组分配单个内存块以及结构中的其他数据(使用指针,您通常最终会得到两个单独分配的块) .

    它对于通过相当多的网络协议传输的数据也很有用,其中输入流以相同的方式定义 - 定义长度的整数,然后是数据的许多单位(通常是字节/八位字节) . 您可以(通常)使用类型双关语将具有灵活数组成员的结构覆盖到填充有此类数据的缓冲区,并直接使用它,而不必将其解析成片段,然后单独处理这些片段 .

  • 4

    C FAQ恰恰回答了这个问题 . 快速回答是这个结构将在结构中包含 double 数组,而不是指向结构外部数组的指针 . 作为一个简单的示例,您可以像在此示例中一样使用您的结构:

    struct s mystruct = malloc(sizeof(struct s) + 5 * sizeof(double));
    s.n = 12;
    s.d[0] = 4.0;
    s.d[1] = 5.0;
    s.d[2] = 6.0;
    s.d[3] = 7.0;
    s.d[4] = 8.0;
    

    等等 - 您关心的数组的大小包含在分配中,然后您可以像任何数组一样使用它 . 通常这样的类型包含作为结构的一部分的大小,因为使用 + 技巧跳过 s 类型的数组将必然因此情况而复杂化 .

    对于你添加的问题'how is this construct any more or less powerful than keeping a [pointer] as the 2nd element?',它本身并没有更强大的功能,但是你不能在多种方式中做到这一点可能是一个很好的解释,但有些情况下你会特别想要一个设计或者其他 .

  • 2

    您可以使用它将头字段添加到动态分配的数组中,其中最常见的是其大小:

    struct int_array
    {
        size_t size;
        int values[];
    };
    
    struct int_array *foo = malloc(sizeof *foo + 42 * sizeof *foo->values);
    foo->size = 42;
    
    ...
    
    for(size_t i = 0; i < foo->size; ++i)
        foo->values[i] = i * i;
    

    您可以通过使用 int * 成员而单独分配数组来获得类似的结果,但是在内存(附加指针,第二个内存块的堆管理)和运行时(附加间接,第二次分配)方面效率都会降低 .

  • 0

    我已经在Windows上看到过用于标记长度的字符串的字符串 . 字符数据直接存储在内存中,将所有内容整齐地保存在一起 .

    typedef struct {
        SIZE_T bytes;
        TCHAR chars[];
    } tagged_string;
    

相关问题