关于C语言数据结构的问题
typedef struct _tag_LinkQueueNode TLinkQueueNode;
struct _tag_LinkQueueNode
{
TLinkQueueNode* next;
void* item;
};
请问在这上面定义的_tag_LinkQueueNode里面的结构体的next是什么意思,是指一个指TLinkQueueNode类型的指针呢?还是一个TLinkQueueNode的结构体?为什么将它改为TLinkQueueNode next,就会报错?
另外,可不可以这么理解,next是一个结构体,这个结构体里面又有另一个TLinkQueueNode结构体,这样子循环下去?
typedef struct _tag_LinkQueue
{
TLinkQueueNode* front;
TLinkQueueNode* rear;
int length;
} TLinkQueue;
typedef struct _tag_LinkQueue
{
TLinkQueueNode front;
TLinkQueueNode rear;
int length;
} TLinkQueue;
另外这两个声明又有什么区别?是不是区另就是上面的front,reat可以直接指向一个TLinkQueueNode的地址,下面的不可以?
你看看你的第一句就知道了,next指针类型就是这个结构体本身。typedef是给一个名称起别名,并不是新建一个类型,所以TLinkQueueNode就是struct _tag_LinkQueueNode。
这个节点一般用来存放下一个节点的地址,将这个节点与另一个节点连接起来,就成了你看到的链表。next是结构体的成员...不是嵌套一个结构体的意思...当然也勉强说的通...
至于第二个问题,他有2个指针,一个向前指,一个向后指,就是说他是一个双向的链表,可以往前,也可以往后。
第一个例子中,他只保存了下一个节点的地址,没有保存前节点地址,所以你只能从前往后找。但双向链表即可以向前也可以向后,所以只要知道了任何一个节点,就可以找出所有的节点了。
[解决办法]
一个是你家房子里桌子的位置,东南西北中啊,一个是桌子,很好理解啊
[解决办法]
就是一个指针 typedef 就像起别名类似
改为 结构体变量就通不过了
就像
typedef struct me ME
struct me
{
ME me;
int elem;
}
这个结构体里的成员me,和 外面的ME一个类型的,它是什么结构类型的,就不可理解了,但如果是指针,就是指向确定大小的内存空间,
[解决办法]
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”
但我又不得不承认:
有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物;
而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。
而我本人属前者。
这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑!
这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!!
提醒:
“学习用汇编语言写程序”
和
“VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
有人说一套做一套,你相信他说的还是相信他做的?
其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗?
不要写连自己也预测不了结果的代码!
电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
十字链表交换任意两个节点C源代码(C指针应用终极挑战)http://download.csdn.net/detail/zhao4zhong1/5532495
[解决办法]
2楼说的就很详细了,顶2楼。
next指针:表示存放了一个 指向TLinkQueueNode结构的 地址。
item指向的 是 真正要用的数据。
这是链式结构的习惯用法。
[解决办法]
补充一句:如果去掉那朵可爱而又美丽的菊花(*),那么编译器会说“你要坑死爹不成?露露式的勒索!!!”因为这成了死循环的分配资源!正所谓:从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的什么呢?讲的是“从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的什么呢?讲的是“从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的什么呢?讲的是“”从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的什么呢?讲的是“”从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的什么呢?讲的是“... ...”””
[解决办法]
typedef定义别名的意思.
typedef struct _tag_LinkQueueNode TLinkQueueNode;
struct _tag_LinkQueueNode
{
TLinkQueueNode* next;
void* item;
};
等价于:
struct _tag_LinkQueueNode
{
struct _tag_LinkQueueNode* next;
void* item;
};
next当然是个指针, 指向一个结构体struct _tag_LinkQueueNode.
学点数据结构就懂了, 这是典型的链表形成的方法.
你可以声明第一个结构体对象: struct _tag_LinkQueueNode node1;
再声明第二个struct _tag_LinkQueueNode node2; 然后node1.next = &node2;(把node2的地址记录在node1的next变量里)
继续struct _tag_LinkQueueNode node3; 然后node2.next = &node3;(把node3的地址记录在node2的next变量里)
这样, 你指通过node1这个头结点, 就可以通过next一个个把后面所有的节点都找到了, 这就是链表了.
(当然链表的节点一般都是malloc出来的, 这里仅为举例方便)
问题2:
两个的声明语法上都正确, 也都能通过里面的front(无论是struct _tag_LinkQueue还是struct _tag_LinkQueue*类型)获得链表的全部节点.
只是链表里的那种成员变量通常都是定义成指针的, 指针变量占用空间小, 32位系统小指针统一是4字节, 如果不定义成指针而是struct _tag_LinkQueue, 那这个成员的大小就多大都有可能了.
所以
typedef struct _tag_LinkQueue
{
TLinkQueueNode* front;
TLinkQueueNode* rear;
int length;
} TLinkQueue;这个结构体的大小永远是sizeof(指针) + sizeof(指针) + sizeof(int) = 4 + 4 + 4 = 12
而typedef struct _tag_LinkQueue
{
TLinkQueueNode front;
TLinkQueueNode rear;
int length;
} TLinkQueue;的大小 = sizeof(TLinkQueueNode ) + sizeof(TLinkQueueNode ) + sizeof(int);
如果TLinkQueueNode 很大, 那么你这个TLinkQueue可就很大了.