打印

看到這樣的數據結構總讓我有種神經錯亂的感覺

[复制链接]
4228|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
eng588|  楼主 | 2010-4-10 11:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
看到這樣的數據結構總讓我有種神經錯亂的感覺:
struct mylink{
   int a;
   struct mylink *p;
   }
mylink還沒聲明完,怎么就用上了mylink的指針?
這好比編譯器問我:張三是誰?
我告訴編譯器:張三是張三哥哥的弟弟。

哪位高人告訴我編譯器究竟是怎樣處理這樣的數據結構的
沙发
ShakaLeo| | 2010-4-10 12:01 | 只看该作者
本帖最后由 ShakaLeo 于 2010-4-10 12:02 编辑

呵呵,定义一个结构体,需要给这个结构体的成员分配内存空间,对ARM来说,一个指针占的空间不会超过4个字节,编译器只需给这个*p分配4个字节的空间,而不必管它是什么类型。
当在下面的程序中使用成员*p时,这个结构体已经定义完了,编译器已经知道了这个指针是什么类型,会根据它的类型进行编译。

使用特权

评论回复
板凳
linjing| | 2010-4-10 13:40 | 只看该作者
没有任何问题,这是典型的链表节点的数据定义方法

针对某个确定的系统,所使用的指针不管是什么类型的,都占有固定的存储长度,所有可以先定义指针,再定义指针所指向的数据类型

使用特权

评论回复
地板
eng588|  楼主 | 2010-4-10 14:14 | 只看该作者
GOOD

使用特权

评论回复
5
eng588|  楼主 | 2010-4-10 14:36 | 只看该作者
兩位高人,我是否可以這樣理解,定義一個數據類型只是讓編譯器知道該類型占用多少字節,在何處存放,此階段編譯器不考慮該類型支持何種運算。
在此后使用該類型時,編譯器才考慮其運算是否合法。

使用特权

评论回复
6
ShakaLeo| | 2010-4-10 14:50 | 只看该作者
大概就是这个意思吧

使用特权

评论回复
7
patson| | 2010-4-10 23:12 | 只看该作者
看不懂!不知编译真的能够按1,2楼所说的那样能依人的思维运行的话,那么上面所说的没有错,但如楼主所说的那样,声明都没有完,就在里面引用了,难道现在的编译器已经发展到能按人的思维来运行了?机器难道真的可以有自己的思想了?不是一步步按优先权来运行吗?

使用特权

评论回复
8
voidx| | 2010-4-11 07:42 | 只看该作者
没必要转牛角尖,
链表节点定义方法。

C语言标准文档给出的一个例子就是这么定义的:
struct int_list { int car; struct int_list *cdr; };

使用特权

评论回复
9
ejack| | 2010-4-11 07:59 | 只看该作者
编译器不知道mylink是什么东西,也不需要知道。
指针的声明只是告诉编译器什么类型需要多少空间而已。

在声明的时候,哪怕你写个
struct ComilerIsSB{
   int a;
   struct ComilerIsSB *p;
   }
编译器也不会跳出来反驳你。

使用特权

评论回复
10
爱国道人| | 2010-4-11 11:03 | 只看该作者
这是一个递归指针,作链表用的。可参考一些数据结构的书

使用特权

评论回复
11
司徒老鹰| | 2010-4-11 13:37 | 只看该作者
看不懂

使用特权

评论回复
12
patson| | 2010-4-11 14:10 | 只看该作者
回头看了下指导书,明白了。

使用特权

评论回复
13
lxyppc| | 2010-4-11 15:08 | 只看该作者
说说我的理解吧
struct mylink{
   int a;
   struct mylink *p;
};
结构体中的struct mylink *p 与结构体声明没有任何关联,struct mylink *p只是告诉编译器,我这里需要为结构体分配一个指针占用的空间,这个指针的类型是struct mylink,这里只是碰巧和结构体的名称一样了。由于指针占用的空间大小是已知的,所以这里编译器并不需要知道struct mylink的细节,它只需要知道这个指针类型应该和struct mylink相匹配就可以了。

使用特权

评论回复
14
lxyppc| | 2010-4-11 15:08 | 只看该作者
说说我的理解吧
struct mylink{
   int a;
   struct mylink *p;
};
结构体中的struct mylink *p 与结构体声明没有任何关联,struct mylink *p只是告诉编译器,我这里需要为结构体分配一个指针占用的空间,这个指针的类型是struct mylink,这里只是碰巧和结构体的名称一样了。由于指针占用的空间大小是已知的,所以这里编译器并不需要知道struct mylink的细节,它只需要知道这个指针类型应该和struct mylink相匹配就可以了。

使用特权

评论回复
15
lxyppc| | 2010-4-11 15:15 | 只看该作者
再说一个我对类型名称的理解
定义指针只需要知道类型名就可以了,不用知道类型的细节
有三种类型名
1. int, float这种内置
2.用typedef定义的。
3.还有一种是用struct/union/enum修辞的。(tag名字空间,可以不用声明直接使用)

int *p; //使用内置类型,没有问题

typedef  int INT32;
INT32 *p; //使用typedef定义的类型,没有问题

struct MyStruct *p;//使用struct修辞的类型,MyStruct可以不用预先声明,可直接使用

使用特权

评论回复
16
秋天落叶| | 2010-4-11 21:16 | 只看该作者
只是先声明,为这个结构体分配空间

使用特权

评论回复
17
sinadz| | 2010-4-11 21:58 | 只看该作者
用法没问题,只是用来申明空间

使用特权

评论回复
18
kiton_law| | 2010-4-20 22:24 | 只看该作者
基本上所有的基于指针的链表都是这么定义的
而楼主张三是张三哥哥的弟弟的理解是错误的。
struct AAA
{
      int  aaa;
      struct AAA *next;  //注意这里是指针,指针的长度是以知的,而这个指针的类型在具体使用的地点才会被编译器检查,而那时struct AAA早已经定义过了
};

同样用张三和他弟弟来比喻,我们把张三哥哥的弟弟(注意是泛指,代表一个类,张三的哥哥可能有多个弟弟,呵呵,是不是有点类似面向对象,其实就是)比作struct AAA这个类型,把张三比作他哥哥的其中一个弟弟(struct AAA类型的一个变量,也是一个张三各个的弟弟类的对象,真绕口),这里应该把next当成张三哥哥的其中一个弟弟的名字(对象的地址),这只是一个名字,它也许是中文写的,也许是英文写的(就好比某些编译器指针是2字节,某些是4字节),而具体这个名字是否是张三的名字(张三是张三哥哥的弟弟,但张三哥哥的弟弟并不一定是张三),不重要,会在以后叫到这个名字(使用地址)的时候来判断,而如果这个名字叫到了一个不是张三哥哥的弟弟的人,就错了(指针类型不匹配)。
所以楼主的认知是错误的,这里还没有形成struct AAA类型的变量,也就不存在张三,next指针对于struct AAA这个结构来说,就相当于张三的哥哥的某个弟弟手里有个纸条,这个纸条必须写上张三哥哥的某个弟弟的名字。而需要写特定名字的纸条和某某人哥哥的某个弟弟显然是两回事。

明白了吧

使用特权

评论回复
19
eng588|  楼主 | 2010-4-23 21:23 | 只看该作者
只能说够复杂,能否把关于这个问题的编译器代码贴出来,
代码最清楚

使用特权

评论回复
20
sinadz| | 2010-4-23 21:55 | 只看该作者
看完诸位的贴,我也有点理不清头绪了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

82

主题

179

帖子

0

粉丝