例程序如下:
#include <stdio.h>
typedef struct sNormNode{
struct sNormNode *ProNode;
struct sNormNode *NextNode;
}NormNode;
typedef struct sTask{
NormNode dataNode; //链表
char data; //数据
}SysTask;
SysTask TaskHeadNode;
SysTask *pTaskHeadNode = &TaskHeadNode;
void NodeInsertEnd(SysTask *List, NormNode *NewNode){// 尾插
//设链表头为a 最后一个节点 b 待插入节点为c
List->dataNode.ProNode->NextNode = NewNode; //b->next = c
NewNode->ProNode = List->dataNode.ProNode; //c->pro = b
NewNode->NextNode = &List->dataNode; //c->next = a
List->dataNode.ProNode = NewNode; //a->pro = c
}
int main(){
int i = 0;
SysTask *Task[5];
SysTask *TargetTask = NULL;
NormNode *TimerNode = NULL;
pTaskHeadNode->dataNode.ProNode = &TaskHeadNode.dataNode;//初始化链表头
TaskHeadNode.dataNode.ProNode = &TaskHeadNode.dataNode;
TaskHeadNode.dataNode.NextNode = &TaskHeadNode.dataNode;
for (i = 0; i < 5; i++){
Task[i] = (SysTask*)malloc(sizeof(SysTask));
Task[i]->data = i;
NodeInsertEnd(&TaskHeadNode, &(Task[i]->dataNode));
}
TimerNode = TaskHeadNode.dataNode.NextNode;
for (i = 0; i < 5; i++){
TargetTask = TimerNode - ((unsigned int)&((SysTask *)0)->dataNode);
//TargetTask = (SysTask *)((unsigned int)TimerNode - ((unsigned int)&((SysTask *)0)->dataNode));
TimerNode = TimerNode->NextNode;
printf("data:%d \n", TargetTask->data);
}
while (1);
}
程序中链表的储存形式如下图,
链表里面就只有上一节点ProNode和下一节点NextNode没有包含着数据data
但是程序中通过
TargetTask = TimerNode - ((unsigned int)&((SysTask *)0)->dataNode);
运算出了链表节点所在的结构体的首地址
然后通过结构体首地址用指针指出了数据data