赞
踩
最近在看代码的时候,发现有一个链表有点奇怪,一下子没看出来个所以,于是好奇地认真的看了下,于是记录下了这篇博文。
首先看使用情况:
- void threadProc()
- {
- ListNode *node = sFdList.head;
- while(node)
- {
- ReactorSocket *reactor = (ReactorSocket*)node;
-
- //to do
- printf("socket fd = %d, reactor addr = %p\n", 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: %p\n", &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) = %lu\n", sizeof(long));
- return 0;
- }
-
-
- void addReactor(List *list, ReactorSocket *reactor)
- {
- printf("add node addr: %p\n", &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 = %d\n", 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 = %p\n", reactor->socket->sockFd, reactor);
-
- node = node->next;
- }
- }
从打印可以看出加入链表时的地址和取出来的地址是一样的,所以能成转换成功。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。