概述
最近在看代码的时候,发现有一个链表有点奇怪,一下子没看出来个所以,于是好奇地认真的看了下,于是记录下了这篇博文。
首先看使用情况:
void threadProc()
{
ListNode *node = sFdList.head;
while(node)
{
ReactorSocket *reactor = (ReactorSocket*)node;
//to do
printf("socket fd = %d, reactor addr = %pn", reactor->socket->sockFd, reactor);
node = node->next;
}
}
node指向了链表的头节点,然后在while循环里取出,再强制转换成ReactorSocket*类型。这里node的类型是指向ListNode类型的指针,ListNode的定义为:
typedef struct node
{
struct node *prev;
struct node *next;
}ListNode;
ReactorSocket的定义为:
typedef struct reactorSock
{
ListNode node;
CSocket *socket;
}ReactorSocket;
第一眼看怎么把node类型的转换成ReactorSocket?其实在添加链表节点是,是这样添加的:
void addReactor(List *list, ReactorSocket *reactor)
{
printf("add node addr: %pn", &reactor->node);
addListNode(list, &reactor->node);
}
void addListNode(List *list, ListNode *node)
{
list->nodeTotal++;
node->next = NULL;
node->prev = NULL;
if(list->tail) //节点添加到尾部
{
list->tail->next = node; //尾节点的next指向新节点
node->prev = list->tail; //新节点的prev指向尾节点
list->tail = node; //更新尾节点,现在node是尾结点
}
else //第一个节点
{
list->head = node;
list->tail = node;
}
}
其中有一句:addListNode(list, &reactor->node);是把ReactorSocket的变量node地址添加到链表中了,其实node的地址不就是ReactorSocket的地址吗,所以才能这样转换:ReactorSocket *reactor = (ReactorSocket*)node;
完整的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/socket.h>
//节点定义
typedef struct node
{
struct node *prev;
struct node *next;
}ListNode;
typedef struct list
{
int nodeTotal;
ListNode *head; //链表头
ListNode *tail; //链表尾
}List;
//以下定义的函数指针中,其函数的参数带有void*,其作用是将对象带进来
typedef struct
{
uint32_t sockFd;
int32_t (*sockSend)(void *, const char *buf, uint32_t len);
int32_t (*sockRecv)(void *, char *buf, uint32_t len);
int32_t (*sockClose)(void *);
void (*sockDestory)(void *);
}CSocket;
typedef struct reactorSock
{
ListNode node;
CSocket *socket;
}ReactorSocket;
void addReactor(List *list, ReactorSocket *reactor);
void addListNode(List *list, ListNode *node);
void threadProc();
int32_t createSock(ReactorSocket *reactor);
static List sFdList;
struct Test
{
char a;
int b;
long c;
};
int main()
{
ReactorSocket *reactor = (ReactorSocket*)malloc(sizeof(ReactorSocket));
int32_t fd = createSock(reactor);
addReactor(&sFdList, reactor);
threadProc();
if(fd > 0)
{
close(fd);
}
free(reactor->socket);
free(reactor);
printf("sizeof(Test) = %lun", sizeof(long));
return 0;
}
void addReactor(List *list, ReactorSocket *reactor)
{
printf("add node addr: %pn", &reactor->node);
addListNode(list, &reactor->node);
}
void addListNode(List *list, ListNode *node)
{
list->nodeTotal++;
node->next = NULL;
node->prev = NULL;
if(list->tail) //节点添加到尾部
{
list->tail->next = node; //尾节点的next指向新节点
node->prev = list->tail; //新节点的prev指向尾节点
list->tail = node; //更新尾节点,现在node是尾结点
}
else //第一个节点
{
list->head = node;
list->tail = node;
}
}
int32_t createSock(ReactorSocket *reactor)
{
int32_t fd = socket(AF_INET, SOCK_STREAM, 0);
printf("create socket fd = %dn", fd);
reactor->socket = (CSocket*)malloc(sizeof(CSocket));
reactor->socket->sockFd = fd;
return fd;
}
void threadProc()
{
ListNode *node = sFdList.head;
while(node)
{
ReactorSocket *reactor = (ReactorSocket*)node;
//to do
printf("socket fd = %d, reactor addr = %pn", reactor->socket->sockFd, reactor);
node = node->next;
}
}
从打印可以看出加入链表时的地址和取出来的地址是一样的,所以能成转换成功。
最后
以上就是舒服煎饼为你收集整理的链表里的struct的全部内容,希望文章能够帮你解决链表里的struct所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复