繁体   English   中英

初始化包含指向其自身类型的指针的常量struct

[英]Initializing constant struct containing pointer to its own type

我有这样的结构:

typedef struct tree_s{
    struct tree_s *a;
    int b;
}tree_t;

目前,我正在以这种方式初始化:

tree_t branch_n = {
    .a = NULL,
    .b = 2
};

tree_t root = {
    .a = (tree_t*) &branch_n, 
    .b = 1
};

现在,让我感到恼火的是我必须在root之前初始化较低的分支,因为完整的结构非常大,分支有自己的分支,使我的代码难以管理。

我想做的是这样的事情:

tree_t root = {
    .a = 
     //The first branch
     {                 
        .a =
         //Yet another branch 
         { //Since the following is actually an array, I need the 
           // "a" above to point to the first index
             {  
                 .a = NULL,         //Maybe this will have its own branch
                 .b = 3
             },
             {
                 .a = 
                 {
                     .a = NULL,     //And this might even have its own branch
                     .b = 5
                 }
                 .b = 4  
             }
         }
        .b = 2
     }, 
    .b = 1
};

我怎样才能实现这样的初始化?

我想这样做的主要原因是为了大大增强我的代码的概述,并立即直观地看到“树”的结构。

请注意,从一开始就知道完整“树”的结构,这就是我认为结构不变的原因。 然而,值b可以随时改变。

我是C语言的新手,这是我关于SO的第一篇文章,所以请随时编辑或询问我是否能够让自己明白:)

选项1a - 一个数组

您的“树”结构似乎卡在一个相当线性的形状,但您可以使用数组来解决问题:

static const tree_t oak[] =
{
    { .a = &oak[1], .b = 20 },
    { .a = &oak[2], .b = 15 },
    { .a = NULL,    .b = 10 },
};

选项1b - 从数组构建的树

或者给出二叉搜索树结构:

#include <stdio.h>

typedef struct bst_t bst_t;
struct bst_t
{
    int          data;
    const bst_t *left;
    const bst_t *right;
};

static const bst_t bst[] =
{
    { .data = 30, .left = &bst[1], .right = &bst[2] },
    { .data = 10, .left = &bst[3], .right = &bst[4] },
    { .data = 50, .left = &bst[5], .right = &bst[6] },
    { .data =  5, .left = &bst[7], .right = &bst[8] },
    { .data = 20, .left =       0, .right = &bst[9] },
    { .data = 40, .left =       0, .right =       0 },
    { .data = 60, .left =       0, .right =       0 },
    { .data =  2, .left =       0, .right =       0 },
    { .data =  8, .left =       0, .right =       0 },
    { .data = 28, .left =       0, .right =       0 },
};

static void print_in_order(const bst_t *bst)
{
    if (bst != 0)
    {
        printf("[");
        print_in_order(bst->left);
        printf("(%d)", bst->data);
        print_in_order(bst->right);
        printf("]");
    }
}

static void print_tree(const bst_t *bst)
{
    print_in_order(bst);
    putchar('\n');
}

int main(void)
{
    print_tree(&bst[0]);
    return 0;
}

这会产生输出:

[[[[(2)](5)[(8)]](10)[(20)[(28)]]](30)[[(40)](50)[(60)]]]

选项2a - C99复合文字

使用C99和复合文字,您可以编写:

#include <stddef.h>

typedef struct tree_s{
    struct tree_s *a;
    int b;
}tree_t;

tree_t root2 =
{
    .a = &(tree_t){ .a = NULL, .b = 2 }, .b = 1
};

tree_t root3 =
{
    .a = &(tree_t){ .a = &(tree_t){ .a = NULL, .b = 3 }, .b = 2 }, .b = 1
};

我不确定它是否清晰,但它编译好。 总的来说,我更喜欢数组符号。

这是OP想要/使用的主要答案。


选项2b - 尝试使阵列进入初始化失败

尝试修改有问题的修改后的数据结构(请记住,可以使用数据结构创建的“树”只是一个单链表),你几乎可以(但不是完全)用这个来做:

tree_t root4 =
{
    .a = &(tree_t)
    {                 
        .a = (tree_t [])
        { 
            (tree_t){  
                .a = NULL,
                .b = 3
            },
            (tree_t){
                .a = &(tree_t)
                {
                    .a = NULL,
                    .b = 5
                },
                .b = 4  
            },
        },  // Line 47
        .b = 2
    }, 
    .b = 1
};

GCC(i686-apple-darwin11-llvm-gcc-4.2(GCC)4.2.1(基于Apple Inc. build 5658)(LLVM build 2336.11.00))在Mac OS X 10.8.4上抱怨:

tree.c:47: error: initializer element is not constant
tree.c:47: error: (near initialization for ‘(anonymous)’)

标记第47行的地方 - 它是结构数组的末尾。 我可能会遗漏一些明显的东西。 我确实试过&(test_t[]){ ... }[0],但是得到了同样的警告。

我完全不确定如何判断特定指针是指向数组开头而不是单个tree_t元素的指针,除非您添加另一个字段来指示差异(或者b字段以某种方式编码以指示a是指向单个项的指针还是指向数组的指针。

我不认为这段代码:

tree_t root = {
    .a = 
     //The first branch
     {                 
        .a = NULL,       //Maybe another branch instead of NULL
        .b = 2
     }, 
    .b = 1
};

将成功初始化tree_t根目录。

{}用于初始化结构,而不是指针。 但root-> a被定义为指针。 您可能会因此而编译错误。

可以在上面的代码之外定义和初始化分支,并将指针root->设置为它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM