数据类型互相定义,先有鸡还是先有蛋?

pkuzhx 2016-01-18 02:29:27
如下是一个头文件中对Task和TaskData的定义。我有点不太理解这种定义方法,定义Task的时候,用到了TaskData类型,而定义TaskData的时候,其成员函数指针有用到了TaskData类型。
这两种类型定义都包含彼此,相互定义,这种定义是怎么工作的?先有鸡还是先有蛋,我有点晕了

/* This file was automatically generated from syscalls.in 17.2 */

#ifndef __MESSAGE__H

#define __MESSAGE__H

#include <csrtypes.h>
/*! @file message_.h @brief Message types */
/*!
Message identifier type.
*/
typedef uint16 MessageId;
/*!
Message delay type.
*/
typedef uint32 Delay;
/*!
Message type.
*/
typedef const void *Message;
/*!
Task type.
*/
typedef struct TaskData *Task;
/*!
TaskData type.
*/
typedef struct TaskData { void (*handler)(Task, MessageId, Message); } TaskData;

#endif

...全文
237 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
pkuzhx 2016-01-20
  • 打赏
  • 举报
回复
引用 10 楼 sholber 的回复:
[quote=引用 9 楼 paschen 的回复:] [quote=引用 8 楼 sholber 的回复:] [quote=引用 6 楼 paschen 的回复:] 下面语句 A定义在typedef之后,仍然是可以的

typedef struct A* Task;

struct A
{

};
首先,没见过这样的“语句”; 其次,这两个struct A是否一样,是否为同一结构类型,还取决于上下文,你没说清楚。[/quote] 你没见过不代表不存在[/quote] 可别狡辩了。你把声明当成语句还有理了? 还有,就你那个例子问题也是大大的。如下例所示,有没有DECL,程序的效果是不同滴。
struct s {char c;};            //DECL

void f (void)
{
    typedef struct s * ps;
    struct s {float f;};
}
虚心一点,不是谁都愿意指出你的错误。 [/quote] 如果注释掉DECL ps使用的是float f的结构,不注释则是上边char c的结构,学习了,不过还是不太懂typedef的时候到底是如何寻找结构s的,是优先向前找,如果前面没有再向后找吗?
pkuzhx 2016-01-20
  • 打赏
  • 举报
回复
引用 14 楼 zhao4zhong1 的回复:
先有一种能描述鸡和蛋以及未来所有概念的语言 先有一种能指向鸡和蛋以及未来所有概念的指针
赵老师总是这么高屋建瓴
paschen 2016-01-19
  • 打赏
  • 举报
回复
引用 12 楼 sholber 的回复:
[quote=引用 11 楼 paschen 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 paschen 的回复:] [quote=引用 8 楼 sholber 的回复:] [quote=引用 6 楼 paschen 的回复:] 下面语句 A定义在typedef之后,仍然是可以的

typedef struct A* Task;

struct A
{

};
首先,没见过这样的“语句”; 其次,这两个struct A是否一样,是否为同一结构类型,还取决于上下文,你没说清楚。[/quote] 你没见过不代表不存在[/quote] 可别狡辩了。你把声明当成语句还有理了? 还有,就你那个例子问题也是大大的。如下例所示,有没有DECL,程序的效果是不同滴。
struct s {char c;};            //DECL

void f (void)
{
    typedef struct s * ps;
    struct s {float f;};
}
虚心一点,不是谁都愿意指出你的错误。 [/quote] 我想你误解我意思了,我只是说可以这样写而已 你给的例子在f函数中有没定义效果当然是不同的,或许你给的例子更有说服力 函数f中的ps表示的是struct s {float f;}指针,而不是全局中在前面的那个 typedef优先在所在的名字空间下寻找,而且也仅在同名称空间中可见的范围内有效[/quote] 不,typedef没有优先在当前块内寻找的说法。 就上例而言,pf的类型并不是指向struct s {float f;}的指针,而是指向struct s {char c;}的指针。[/quote] 是的,我 这句说错了
均陵鼠侠 2016-01-19
  • 打赏
  • 举报
回复
引用 11 楼 paschen 的回复:
[quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 paschen 的回复:] [quote=引用 8 楼 sholber 的回复:] [quote=引用 6 楼 paschen 的回复:] 下面语句 A定义在typedef之后,仍然是可以的

typedef struct A* Task;

struct A
{

};
首先,没见过这样的“语句”; 其次,这两个struct A是否一样,是否为同一结构类型,还取决于上下文,你没说清楚。[/quote] 你没见过不代表不存在[/quote] 可别狡辩了。你把声明当成语句还有理了? 还有,就你那个例子问题也是大大的。如下例所示,有没有DECL,程序的效果是不同滴。
struct s {char c;};            //DECL

void f (void)
{
    typedef struct s * ps;
    struct s {float f;};
}
虚心一点,不是谁都愿意指出你的错误。 [/quote] 我想你误解我意思了,我只是说可以这样写而已 你给的例子在f函数中有没定义效果当然是不同的,或许你给的例子更有说服力 函数f中的ps表示的是struct s {float f;}指针,而不是全局中在前面的那个 typedef优先在所在的名字空间下寻找,而且也仅在同名称空间中可见的范围内有效[/quote] 不,typedef没有优先在当前块内寻找的说法。 就上例而言,pf的类型并不是指向struct s {float f;}的指针,而是指向struct s {char c;}的指针。
paschen 2016-01-19
  • 打赏
  • 举报
回复
引用 10 楼 sholber 的回复:
[quote=引用 9 楼 paschen 的回复:]
[quote=引用 8 楼 sholber 的回复:]
[quote=引用 6 楼 paschen 的回复:]
下面语句 A定义在typedef之后,仍然是可以的


typedef struct A* Task;

struct A
{

};


首先,没见过这样的“语句”;
其次,这两个struct A是否一样,是否为同一结构类型,还取决于上下文,你没说清楚。[/quote]

你没见过不代表不存在[/quote]

可别狡辩了。你把声明当成语句还有理了?
还有,就你那个例子问题也是大大的。如下例所示,有没有DECL,程序的效果是不同滴。
struct s {char c;};            //DECL

void f (void)
{
typedef struct s * ps;
struct s {float f;};
}

虚心一点,不是谁都愿意指出你的错误。
[/quote]

我想你误解我意思了,我只是说可以这样写而已
你给的例子在f函数中有没定义效果当然是不同的,或许你给的例子更有说服力
函数f中的ps表示的是struct s {float f;}指针,而不是全局中在前面的那个
typedef优先在所在的名字空间下寻找,而且也仅在同名称空间中可见的范围内有效
均陵鼠侠 2016-01-19
  • 打赏
  • 举报
回复
引用 9 楼 paschen 的回复:
[quote=引用 8 楼 sholber 的回复:] [quote=引用 6 楼 paschen 的回复:] 下面语句 A定义在typedef之后,仍然是可以的

typedef struct A* Task;

struct A
{

};
首先,没见过这样的“语句”; 其次,这两个struct A是否一样,是否为同一结构类型,还取决于上下文,你没说清楚。[/quote] 你没见过不代表不存在[/quote] 可别狡辩了。你把声明当成语句还有理了? 还有,就你那个例子问题也是大大的。如下例所示,有没有DECL,程序的效果是不同滴。
struct s {char c;};            //DECL

void f (void)
{
    typedef struct s * ps;
    struct s {float f;};
}
虚心一点,不是谁都愿意指出你的错误。
赵4老师 2016-01-19
  • 打赏
  • 举报
回复
先有一种能描述鸡和蛋以及未来所有概念的语言 先有一种能指向鸡和蛋以及未来所有概念的指针
paschen 2016-01-18
  • 打赏
  • 举报
回复
引用 8 楼 sholber 的回复:
[quote=引用 6 楼 paschen 的回复:]
下面语句 A定义在typedef之后,仍然是可以的


typedef struct A* Task;

struct A
{

};


首先,没见过这样的“语句”;
其次,这两个struct A是否一样,是否为同一结构类型,还取决于上下文,你没说清楚。[/quote]

你没见过不代表不存在
均陵鼠侠 2016-01-18
  • 打赏
  • 举报
回复
引用 6 楼 paschen 的回复:
下面语句 A定义在typedef之后,仍然是可以的

typedef struct A* Task;

struct A
{

};
首先,没见过这样的“语句”; 其次,这两个struct A是否一样,是否为同一结构类型,还取决于上下文,你没说清楚。
均陵鼠侠 2016-01-18
  • 打赏
  • 举报
回复
引用 1 楼 ghx287524027 的回复:
这个有点链表的意味。比如: typedef struct ugl_node { struct ugl_node *pNext; struct ugl_node *pPrev; struct ugl_list *pList; } UGL_NODE; 哪怕还没有声明struct ugl_node,也照样可以使用struct ugl_node *pNext。因为编译器完全可以识别出这是指向结构体的指针,但是只有定义了结构体ugl_node之后,才可以进行解引用操作如*pNext,即pNext的用处是极度受限的。不过只要struct ugl_node的定义完成(遇到对应的右大括号),这样的限制也就消失,在后面的代码中完全可以正常的使用……
这种回答是自信过头了。
paschen 2016-01-18
  • 打赏
  • 举报
回复
这种定义是合法的,你也可以写成:

typedef struct TaskData { void (*handler)(struct TaskData*, MessageId, Message); } TaskData;
paschen 2016-01-18
  • 打赏
  • 举报
回复
下面语句 A定义在typedef之后,仍然是可以的


typedef struct A* Task;

struct A
{

};
pkuzhx 2016-01-18
  • 打赏
  • 举报
回复
顶一顶,希望有更浅显的解释
苏叔叔 2016-01-18
  • 打赏
  • 举报
回复
如果嵌套类型的使用,递归定义,导致size无法确定了,就会有逻辑问题。 但使用指针是没有问题的,因为32位下指针总是4个字节的,大小确定,无歧义。
pkuzhx 2016-01-18
  • 打赏
  • 举报
回复
引用 1 楼 ghx287524027 的回复:
这个有点链表的意味。比如: typedef struct ugl_node { struct ugl_node *pNext; struct ugl_node *pPrev; struct ugl_list *pList; } UGL_NODE; 哪怕还没有声明struct ugl_node,也照样可以使用struct ugl_node *pNext。因为编译器完全可以识别出这是指向结构体的指针,但是只有定义了结构体ugl_node之后,才可以进行解引用操作如*pNext,即pNext的用处是极度受限的。不过只要struct ugl_node的定义完成(遇到对应的右大括号),这样的限制也就消失,在后面的代码中完全可以正常的使用……
链表是用自己定义自己,这个是用别人定义自己,而别人又是用自己去定义的,好像有点不一样,我再体会一下。。
ghx287524027 2016-01-18
  • 打赏
  • 举报
回复
这个有点链表的意味。比如: typedef struct ugl_node { struct ugl_node *pNext; struct ugl_node *pPrev; struct ugl_list *pList; } UGL_NODE; 哪怕还没有声明struct ugl_node,也照样可以使用struct ugl_node *pNext。因为编译器完全可以识别出这是指向结构体的指针,但是只有定义了结构体ugl_node之后,才可以进行解引用操作如*pNext,即pNext的用处是极度受限的。不过只要struct ugl_node的定义完成(遇到对应的右大括号),这样的限制也就消失,在后面的代码中完全可以正常的使用……

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧