Typedef Struct在C编程中的使用
Usage of Typedef Struct in C programming
我有一个 C 模板,作为作业给我。但是在做作业之前,我需要清楚地了解"typedef"和"struct"的用法,才能继续编码。这是代码;
typedef struct NODE_s *NODE;
typedef struct NODE_s
{
NODE right;
NODE left;
unsigned long data;
int height;
} NODE_t[1];
typedef struct TREE_s *TREE;
typedef struct TREE_s
{
NODE root;
} TREE_t[1];
TREE tree_init();
NODE node_init(unsigned long data);
首先,typedef struct NODE_s *NODE;
行在这里做什么?为什么它被命名为带有 *
的指针?
那么在struct定义之后,创建一个名为NODE_t[1]
的变量的目的是什么,就是方括号中的数字"1"连接的东西一个数组,还是别的东西?
最后,声明tree_init();
和node_init(unsigned long data);
函数时,为什么TREE和NODE数据类型名称相反,它们在结构定义之前被声明为 *TREE
和 *NODE
?谢谢你的回答。
给你的模板是这样的,为了便于参考,我在其中的一些行中添加了数字:
typedef struct NODE_s *NODE; // 1
typedef struct NODE_s // 2
{
NODE right; // 3
NODE left;
unsigned long data;
int height;
} NODE_t[1]; // 4
typedef struct TREE_s *TREE;
typedef struct TREE_s
{
NODE root;
} TREE_t[1];
TREE tree_init(); // 5
NODE node_init(unsigned long data);
这里有什么问题?
- 如评论中所述,SO Q&A Is it a good idea to typedef pointers 表明 typedef 指针不是一个好主意,'pointers to functions'(此处不相关)和也许(但可能不是) 对于不透明类型。这一行做了两件事:(1) 它说“有一个带有标签
NODE_s
的结构类型;(2) 名称 NODE
是 struct NODE_s *
的同义词。结构类型是目前不完整;没有关于其成员的详细信息。
- 这一行开始了一个新的
typedef
,但也开始了类型 struct NODE_s
的定义(因为下一行后面跟着 {
)。
- 类型
NODE
已知;它可以在这里使用。意思和你写 struct NODE_s *right;
. 一样
- 名称
NODE_t
是类型struct NODE_s[1]
的别名,一个1struct NODE_s
的数组。目前尚不清楚这将用于什么目的。我(充其量)对其存在持保留意见。 (也可以将第1、2、4点的讨论适用于struct TREE_s
类型,比照。)
- 这是函数声明,但不是原型声明。它说
tree_init()
函数可以用任何数量的任何类型的参数调用,因为没有指定有关这些参数的数量或类型的信息。我们确实知道它不是可变参数函数(可变参数列表,如 printf()
),因为那些 必须 在作用域中以 , ...)
结尾的完整原型声明在它们之前被使用。如果您想指定该函数不带参数,请这样说:TREE tree_init(void);
.
我认为 NODE_t
和 TREE_t
类型背后的意图是允许您编写,例如:
int main(void)
{
TREE_t x = { 0 };
if (x->root != 0)
return 1;
return 0;
}
与在测试中使用 struct NODE_s x
和 x.root
相比,我不确定这是否足以保证类型。它确实使您不必在将指针传递给函数时添加 &
;同样,我不确定它是否真的有足够的帮助来保证它的存在。
我希望看到的模板是:
typedef struct NODE_s NODE;
struct NODE_s
{
NODE *right;
NODE *left;
unsigned long data;
int height;
};
typedef struct TREE_s TREE;
struct TREE_s
{
NODE *root;
};
extern TREE *tree_init(void);
extern NODE *node_init(unsigned long data);
这从 typedef
语句中删除了指针,避免了有些特殊的数组类型,并使用 tree_init()
的显式原型。我个人更喜欢用 extern
标记的函数声明;在 header 中,它们将在 header 中声明的罕见全局变量上匹配 extern
。许多人不喜欢使用 extern
,因为编译器无论如何都会假设——就这样吧;最重要的是一致性。
main()
中的代码现在可以写成:
int main(void)
{
TREE x = { 0 };
if (x.root != 0)
return 1;
return 0;
}
有什么区别?箭头 ->
更改为点 .
。那里没有太多问题。但是,在调用函数时,您可能会使用 &x
而对于 TREE_t
类型,您只需编写 x
(因为它是一个数组)。
我有一个 C 模板,作为作业给我。但是在做作业之前,我需要清楚地了解"typedef"和"struct"的用法,才能继续编码。这是代码;
typedef struct NODE_s *NODE;
typedef struct NODE_s
{
NODE right;
NODE left;
unsigned long data;
int height;
} NODE_t[1];
typedef struct TREE_s *TREE;
typedef struct TREE_s
{
NODE root;
} TREE_t[1];
TREE tree_init();
NODE node_init(unsigned long data);
首先,typedef struct NODE_s *NODE;
行在这里做什么?为什么它被命名为带有 *
的指针?
那么在struct定义之后,创建一个名为NODE_t[1]
的变量的目的是什么,就是方括号中的数字"1"连接的东西一个数组,还是别的东西?
最后,声明tree_init();
和node_init(unsigned long data);
函数时,为什么TREE和NODE数据类型名称相反,它们在结构定义之前被声明为 *TREE
和 *NODE
?谢谢你的回答。
给你的模板是这样的,为了便于参考,我在其中的一些行中添加了数字:
typedef struct NODE_s *NODE; // 1
typedef struct NODE_s // 2
{
NODE right; // 3
NODE left;
unsigned long data;
int height;
} NODE_t[1]; // 4
typedef struct TREE_s *TREE;
typedef struct TREE_s
{
NODE root;
} TREE_t[1];
TREE tree_init(); // 5
NODE node_init(unsigned long data);
这里有什么问题?
- 如评论中所述,SO Q&A Is it a good idea to typedef pointers 表明 typedef 指针不是一个好主意,'pointers to functions'(此处不相关)和也许(但可能不是) 对于不透明类型。这一行做了两件事:(1) 它说“有一个带有标签
NODE_s
的结构类型;(2) 名称NODE
是struct NODE_s *
的同义词。结构类型是目前不完整;没有关于其成员的详细信息。 - 这一行开始了一个新的
typedef
,但也开始了类型struct NODE_s
的定义(因为下一行后面跟着{
)。 - 类型
NODE
已知;它可以在这里使用。意思和你写struct NODE_s *right;
. 一样
- 名称
NODE_t
是类型struct NODE_s[1]
的别名,一个1struct NODE_s
的数组。目前尚不清楚这将用于什么目的。我(充其量)对其存在持保留意见。 (也可以将第1、2、4点的讨论适用于struct TREE_s
类型,比照。) - 这是函数声明,但不是原型声明。它说
tree_init()
函数可以用任何数量的任何类型的参数调用,因为没有指定有关这些参数的数量或类型的信息。我们确实知道它不是可变参数函数(可变参数列表,如printf()
),因为那些 必须 在作用域中以, ...)
结尾的完整原型声明在它们之前被使用。如果您想指定该函数不带参数,请这样说:TREE tree_init(void);
.
我认为 NODE_t
和 TREE_t
类型背后的意图是允许您编写,例如:
int main(void)
{
TREE_t x = { 0 };
if (x->root != 0)
return 1;
return 0;
}
与在测试中使用 struct NODE_s x
和 x.root
相比,我不确定这是否足以保证类型。它确实使您不必在将指针传递给函数时添加 &
;同样,我不确定它是否真的有足够的帮助来保证它的存在。
我希望看到的模板是:
typedef struct NODE_s NODE;
struct NODE_s
{
NODE *right;
NODE *left;
unsigned long data;
int height;
};
typedef struct TREE_s TREE;
struct TREE_s
{
NODE *root;
};
extern TREE *tree_init(void);
extern NODE *node_init(unsigned long data);
这从 typedef
语句中删除了指针,避免了有些特殊的数组类型,并使用 tree_init()
的显式原型。我个人更喜欢用 extern
标记的函数声明;在 header 中,它们将在 header 中声明的罕见全局变量上匹配 extern
。许多人不喜欢使用 extern
,因为编译器无论如何都会假设——就这样吧;最重要的是一致性。
main()
中的代码现在可以写成:
int main(void)
{
TREE x = { 0 };
if (x.root != 0)
return 1;
return 0;
}
有什么区别?箭头 ->
更改为点 .
。那里没有太多问题。但是,在调用函数时,您可能会使用 &x
而对于 TREE_t
类型,您只需编写 x
(因为它是一个数组)。