Typedef Struct在C编程中的使用

奥赞(Ozan Yurtsever)

我有一个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();andnode_init(unsigned long data);函数,为什么使用TREENODE数据类型名称*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);

这里有什么问题?

  1. 如评论中所述,SO Q&A typedef指针是否是一个好主意,暗示typedef指针不是一个好主意,“函数指针”的例外情况有限(此处不相关),也许(但可能不是)不透明的类型。这行代码有两件事:(1)说“存在带有标签的结构类型NODE_s;(2)名称NODE是的同义词struct NODE_s *。该结构类型目前尚不完整;尚无关于其成员的详细信息。
  2. 该行开始一个new typedef,但也开始该类型的定义struct NODE_s(因为{下一行之后是)。
  3. 类型NODE是已知的;它可以在这里使用。它的含义与您写的相同struct NODE_s *right;
  4. 名称NODE_t是该类型的别名struct NODE_s[1],为1的数组struct NODE_s目前尚不清楚这将用于什么用途。我对它的存在(至多)持保留态度。(您也可以将第1、2、4点中的讨论应用于struct TREE_s必要的变型。)
  5. 这是一个函数声明,但不是原型声明。它说tree_init()可以用任何数量的任何类型的参数调用函数,因为没有指定有关这些参数的数量或类型的信息。我们确实知道它不是可变参数函数(可变参数列表,如printf()),因为在使用它们之前,必须具有完整的原型声明, ...),其范围以scope结尾如果要指定该函数不带参数,请说:TREE tree_init(void);

我认为NODE_tTREE_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; 在标头中,它们将与extern标头中声明的那些罕见的全局变量相匹配许多人宁愿不使用它,extern因为无论如何编译器都会假定这样做。最重要的是一致性。

现在中的代码main()将被编写为:

int main(void)
{
    TREE x = { 0 };

    if (x.root != 0)
        return 1;
    return 0;
}

区别?箭头->变成了点.那里没有很多问题。但是,在调用函数时,您可能会使用&xTREE_t类型,则只需编写x(因为它是一个数组)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章