我有这样的结构:
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
};
现在,让我很烦,我有根之前初始化较低的树枝,因为整个结构是相当大的,具有自己的分支机构分支机构,使我的代码难于管理。
我想这样做是这样的:
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
};
我不知道它是清晰的,但它编译OK。 就整体而言,我更喜欢数组符号,虽然。
这是主要的答案是,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的 - 苹果darwin11-LLVM-GCC-4.2(GCC)4.2.1(基于苹果公司建立5658)(LLVM建设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根。
的{}是用于初始化一个结构,而不是一个指针。 但根 - >一个被定义为一个指针。 你可能会得到这个编译错误。
分支可以被定义和上面的代码外初始化,并设置指针根 - >一个指向它。