user-0 提问: 数据类型互相定义，先有鸡还是先有蛋？

回复:
user: user-0
content: 引用 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的，是优先向前找，如果前面没有再向后找吗？

user: user-0
content: 引用 14 楼 zhao4zhong1 的回复:先有一种能描述鸡和蛋以及未来所有概念的语言 先有一种能指向鸡和蛋以及未来所有概念的指针 赵老师总是这么高屋建瓴

user: user-1
content: 引用 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]  是的，我 这句说错了

user: user-2
content: 引用 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;}的指针。

user: user-1
content: 引用 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优先在所在的名字空间下寻找，而且也仅在同名称空间中可见的范围内有效

user: user-2
content: 引用 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;}; } 虚心一点，不是谁都愿意指出你的错误。

user: user-3
content: 先有一种能描述鸡和蛋以及未来所有概念的语言 先有一种能指向鸡和蛋以及未来所有概念的指针

user: user-1
content: 引用 8 楼 sholber 的回复:[quote=引用 6 楼 paschen 的回复:] 下面语句 A定义在typedef之后，仍然是可以的   typedef struct A* Task;  struct A {  };   首先，没见过这样的“语句”； 其次，这两个struct A是否一样，是否为同一结构类型，还取决于上下文，你没说清楚。[/quote]  你没见过不代表不存在

user: user-2
content: 引用 6 楼 paschen 的回复:下面语句 A定义在typedef之后，仍然是可以的   typedef struct A* Task;  struct A {  };   首先，没见过这样的“语句”； 其次，这两个struct A是否一样，是否为同一结构类型，还取决于上下文，你没说清楚。

user: user-2
content: 引用 1 楼 user-5 的回复:这个有点链表的意味。比如： 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的定义完成（遇到对应的右大括号），这样的限制也就消失，在后面的代码中完全可以正常的使用……  这种回答是自信过头了。

user: user-1
content: 这种定义是合法的，你也可以写成：   typedef struct TaskData { void (*handler)(struct TaskData*, MessageId, Message); } TaskData;

user: user-1
content: 下面语句 A定义在typedef之后，仍然是可以的   typedef struct A* Task;  struct A {  };

user: user-0
content: 顶一顶，希望有更浅显的解释

user: user-4
content: 如果嵌套类型的使用，递归定义，导致size无法确定了，就会有逻辑问题。 但使用指针是没有问题的，因为32位下指针总是4个字节的，大小确定，无歧义。

user: user-0
content: 引用 1 楼 user-5 的回复:这个有点链表的意味。比如： 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的定义完成（遇到对应的右大括号），这样的限制也就消失，在后面的代码中完全可以正常的使用…… 链表是用自己定义自己，这个是用别人定义自己，而别人又是用自己去定义的，好像有点不一样，我再体会一下。。

user: user-5
content: 这个有点链表的意味。比如： 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的定义完成（遇到对应的右大括号），这样的限制也就消失，在后面的代码中完全可以正常的使用……