初始化含有指向其自己的类型恒定结构 [英] Initializing constant struct containing pointer to its own type

查看:144
本文介绍了初始化含有指向其自己的类型恒定结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的结构:

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

其中,此刻,我初始化是这样的:

Which, at the moment, I am initializing in this way:

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

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

现在,这让我很烦,我有根前初始化较低的树枝,因为整个结构是相当大的,具有对自己的分支机构树枝上,让我的code难以管理。

Now, it annoys me that I have to initialize the lower branches before the root because the complete structure is quite large, with the branches having branches on their own, making my code hard to manage.

我想什么做的是这样的:

What I would like to do is something like this:

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
};

我如何能实现初始化这个样子?

How can I achieve an initialization like this?

主要的原因我想这样做是为了大大提高我的code的概述,并立即直观地看到的树的结构。

The main reason I want to do this is to greatly enhance the overview of my code and immediately visually see the structure of the "Tree".

需要注意的是完整的树的结构是由这就是为什么我认为结构常数开始知道了。 b值但是可以在任何时候被改变。

Note that the structure of the complete "Tree" is know from the start which is why I consider the structure constant. The value b however may be changed at any time.

我很新的C语言,这是我的第一篇文章上的SO,可以随意编辑或问,如果我还能够说清楚了:)

I am quite new to the C language and this is my first post on SO, so feel free to edit or ask if I havent been able to make myself clear :)

推荐答案

您树结构似乎与一个相当线形被卡住,但你可以使用数组来解决这个问题:

Option 1a — An array

Your 'tree' structure seems to be stuck with a rather linear shape, but you can use an array to get around the problem:

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

选项1B - 从阵列构建的树

或给予二叉搜索树结构:

Option 1b — A tree built from an array

Or given a binary search tree structure:

#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和复合文字,你可以写:


Option 2a — C99 compound literals

With C99 and compound literals, you can write:

#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
};

我不知道它是清晰的,但它编译确定。整体上,我preFER的数组符号,虽然。

I'm not sure that it is legible, but it compiles OK. On the whole, I prefer the array notation, though.

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

This is the primary answer that the OP wanted/used.

试图适应有关的修正后的数据结构(在铭记树可以与该数据结构被创建仅一个单链表),则可以几乎(但不完全)与此做

Attempting to adapt the revised data structure in question (bearing in mind that the 'tree' that can be created with the data structure is only a singly-linked list), you can almost (but not quite) do it with this:

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的-苹果darwin11-LLVM-GCC-4.2(GCC)4.2.1(基于苹果公司建立5658)(LLVM建设2336.11.00))在Mac OS X 10.8.4抱怨:

GCC (i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)) on Mac OS X 10.8.4 complains:

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

其中线47被标记 - 它是结构的阵列的末尾。我可能失去了一些东西明显。我曾尝试&放大器;(test_t []){...} [0] 但得到了同样的警告。

我不敢肯定你怎么能告诉具体的指针是一个指向数组的指针,而不是一个单一的 tree_t 元素的开始,除非添加另一个字段来指示差异(或 b 字段是某种连接$ C $光盘注明是否 A 是的指针中的单个项目或一个指针数组)。

I'm not at all sure how you could tell that the particular pointer was a pointer to the start of an array rather than a single tree_t element, unless you add another field to indicate the difference (or the b field is somehow encoded to indicate whether the a is a pointer to a single item or a pointer to an array).

这篇关于初始化含有指向其自己的类型恒定结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆