当前位置:   article > 正文

链表里的struct_链表的struck结构

链表的struck结构

最近在看代码的时候,发现有一个链表有点奇怪,一下子没看出来个所以,于是好奇地认真的看了下,于是记录下了这篇博文。

首先看使用情况:

  1. void threadProc()
  2. {
  3. ListNode *node = sFdList.head;
  4. while(node)
  5. {
  6. ReactorSocket *reactor = (ReactorSocket*)node;
  7. //to do
  8. printf("socket fd = %d, reactor addr = %p\n", reactor->socket->sockFd, reactor);
  9. node = node->next;
  10. }
  11. }

node指向了链表的头节点,然后在while循环里取出,再强制转换成ReactorSocket*类型。这里node的类型是指向ListNode类型的指针,ListNode的定义为:

  1. typedef struct node
  2. {
  3. struct node *prev;
  4. struct node *next;
  5. }ListNode;

ReactorSocket的定义为:

  1. typedef struct reactorSock
  2. {
  3. ListNode node;
  4. CSocket *socket;
  5. }ReactorSocket;

 第一眼看怎么把node类型的转换成ReactorSocket?其实在添加链表节点是,是这样添加的:

  1. void addReactor(List *list, ReactorSocket *reactor)
  2. {
  3. printf("add node addr: %p\n", &reactor->node);
  4. addListNode(list, &reactor->node);
  5. }
  6. void addListNode(List *list, ListNode *node)
  7. {
  8. list->nodeTotal++;
  9. node->next = NULL;
  10. node->prev = NULL;
  11. if(list->tail) //节点添加到尾部
  12. {
  13. list->tail->next = node; //尾节点的next指向新节点
  14. node->prev = list->tail; //新节点的prev指向尾节点
  15. list->tail = node; //更新尾节点,现在node是尾结点
  16. }
  17. else //第一个节点
  18. {
  19. list->head = node;
  20. list->tail = node;
  21. }
  22. }

其中有一句:addListNode(list, &reactor->node);是把ReactorSocket的变量node地址添加到链表中了,其实node的地址不就是ReactorSocket的地址吗,所以才能这样转换:ReactorSocket *reactor = (ReactorSocket*)node;

完整的代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. //节点定义
  7. typedef struct node
  8. {
  9. struct node *prev;
  10. struct node *next;
  11. }ListNode;
  12. typedef struct list
  13. {
  14. int nodeTotal;
  15. ListNode *head; //链表头
  16. ListNode *tail; //链表尾
  17. }List;
  18. //以下定义的函数指针中,其函数的参数带有void*,其作用是将对象带进来
  19. typedef struct
  20. {
  21. uint32_t sockFd;
  22. int32_t (*sockSend)(void *, const char *buf, uint32_t len);
  23. int32_t (*sockRecv)(void *, char *buf, uint32_t len);
  24. int32_t (*sockClose)(void *);
  25. void (*sockDestory)(void *);
  26. }CSocket;
  27. typedef struct reactorSock
  28. {
  29. ListNode node;
  30. CSocket *socket;
  31. }ReactorSocket;
  32. void addReactor(List *list, ReactorSocket *reactor);
  33. void addListNode(List *list, ListNode *node);
  34. void threadProc();
  35. int32_t createSock(ReactorSocket *reactor);
  36. static List sFdList;
  37. struct Test
  38. {
  39. char a;
  40. int b;
  41. long c;
  42. };
  43. int main()
  44. {
  45. ReactorSocket *reactor = (ReactorSocket*)malloc(sizeof(ReactorSocket));
  46. int32_t fd = createSock(reactor);
  47. addReactor(&sFdList, reactor);
  48. threadProc();
  49. if(fd > 0)
  50. {
  51. close(fd);
  52. }
  53. free(reactor->socket);
  54. free(reactor);
  55. printf("sizeof(Test) = %lu\n", sizeof(long));
  56. return 0;
  57. }
  58. void addReactor(List *list, ReactorSocket *reactor)
  59. {
  60. printf("add node addr: %p\n", &reactor->node);
  61. addListNode(list, &reactor->node);
  62. }
  63. void addListNode(List *list, ListNode *node)
  64. {
  65. list->nodeTotal++;
  66. node->next = NULL;
  67. node->prev = NULL;
  68. if(list->tail) //节点添加到尾部
  69. {
  70. list->tail->next = node; //尾节点的next指向新节点
  71. node->prev = list->tail; //新节点的prev指向尾节点
  72. list->tail = node; //更新尾节点,现在node是尾结点
  73. }
  74. else //第一个节点
  75. {
  76. list->head = node;
  77. list->tail = node;
  78. }
  79. }
  80. int32_t createSock(ReactorSocket *reactor)
  81. {
  82. int32_t fd = socket(AF_INET, SOCK_STREAM, 0);
  83. printf("create socket fd = %d\n", fd);
  84. reactor->socket = (CSocket*)malloc(sizeof(CSocket));
  85. reactor->socket->sockFd = fd;
  86. return fd;
  87. }
  88. void threadProc()
  89. {
  90. ListNode *node = sFdList.head;
  91. while(node)
  92. {
  93. ReactorSocket *reactor = (ReactorSocket*)node;
  94. //to do
  95. printf("socket fd = %d, reactor addr = %p\n", reactor->socket->sockFd, reactor);
  96. node = node->next;
  97. }
  98. }

 从打印可以看出加入链表时的地址和取出来的地址是一样的,所以能成转换成功。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/537068?site
推荐阅读
相关标签
  

闽ICP备14008679号