前言
最近看代码的时候看到了许多地方使用TailQ这个数据结构来组织数据,在过往的项目中一般都是直接使用的list这个链表的。稍微看了 一下代码的实现, 其实就是一个双向链表的实现,抽象出链表头保存头尾元素,然后链表的关系结构存放在具体节点的filed域,提供一些常用宏的封装而已。链表成员关系主要如图所示:
使用
稍微写了一个demo示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>
struct node {
int value;
TAILQ_ENTRY(node) link;
/*
struct {
struct node **prev;
struct node *next;
} link;
*/
};
TAILQ_HEAD(heads, node); // define a struct for tailq list
#if 0
struct heads {
struct type *tqh_first; /* first element */
struct type **tqh_last; /* addr of last next element */
}
#endif
struct heads my_list;
/*
https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gcc/Common-Function-Attributes.html
*/
__attribute__((constructor(101))) void init101() {
printf("call %s\r\n", __FUNCTION__);
}
__attribute__((constructor(102))) void init102() {
printf("call %s, init tailq my_list\r\n", __FUNCTION__);
TAILQ_INIT(&my_list);
}
__attribute__((destructor)) void dealloc() {
printf("call dealloc free tail my_list\r\n");
struct node *ele = TAILQ_FIRST(&my_list);
while (ele) {
struct node *prev = ele;
ele = TAILQ_NEXT(ele, link);
TAILQ_REMOVE(&my_list, prev, link);
free(prev);
}
printf("After dealloc , list empty %d\r\n", TAILQ_EMPTY(&my_list)?1:0);
}
int main() {
int i, value;
struct node *ele = NULL;
for (i = 0; i < 5; i++) {
printf("enter %d elememt:\r\n", i);
scanf("%d", &value);
ele = (struct node *)malloc(sizeof(struct node));
ele->value = value;
TAILQ_INSERT_TAIL(&my_list, ele, link);
}
printf("TailQ content:\r\n");
TAILQ_FOREACH(ele, &my_list, link) {
printf("%d \r\n", ele->value);
}
printf("After main , list empty %d\r\n", TAILQ_EMPTY(&my_list)?1:0);
return 0;
}
/*
gcc tailq.c -o q
./q
*/
复制代码
执行效果:
call init101
call init102, init tailq my_list
enter 0 elememt:
3
enter 1 elememt:
4
enter 2 elememt:
5
enter 3 elememt:
2
enter 4 elememt:
3
TailQ content:
3
4
5
2
3
After main , list empty 0
dealloc free tail my_list
After dealloc , list empty 1
复制代码
更多
学习一个数据结构或者新的API接口,最好的方法就是搞懂其原理后,动手写个小demo,化抽象为具体,真切的体验一下。代码中还掺杂了对__attribute的使用。
更多2
刚入职的时候配置那个gitlab之后,ssh死活连不上去, 原来是为了安全,gitlab的ssh端口号改了,不是默认的22。按照默认的配置是连接不上去的, 这个时候可以在~/.ssh/config里面指定配置端口号:
root@keep-VirtualBox:~/.ssh# cat config
Host gitlab.xxx.com.cn
IdentityFile ~/.ssh/id_rsa
User keep
Port 88088
Host gitee.com
IdentityFile ~/.ssh/id_ed25519_qq
User fishmwei
复制代码
可以配置不同的证书、端口号以及对应的用户名,真的很方便,又学了一招。
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。
博客地址: fishmwei.gitee.io/ 掘金主页: juejin.cn/user/208432…