C语言作为面向过程的语言,想写出灵活的结构与封装需要很高技巧。
但由于C语言的高效,几乎所有操作系统和面向对象语言的最底层实现都使用了C语言。即,使用C完成面向对象的封装。
这次通过整理与仿写Linux的双向链表让我体会到了一些C语言封装的核心技巧。
这个双向链表的巧妙之处在于1)利用宏将“函数”入参扩展出了“结构类型”; 2)利用纯地址偏移获取结构体指针;
下面是具体实现:链表的实现由于是宏定义,都在libList.h中。
测试程序testList.c与testList.h。
libList.h
#ifndef _LIBLIST_H
#define _LIBLIST_H
#ifdef __cplusplus
extern "C" {
#endif
/* 链表头节点定义 */
typedef struct tagstList_Head {
struct tagstList_Head *next, *prev;
}stList_Head;
/* 初始化双向链表 */
#define list_init(head) do \
{ \
(head)->next = (head)->prev = (head); \
} while(0)
/* 在指定元素(where)之后插入新元素(item) */
#define list_add(item, towhere) do \
{ \
(item)->next = (towhere)->next; \
(item)->prev = (towhere); \
(towhere)->next = (item); \
(item)->next->prev = (item); \
} while(0)
/* 在指定元素(where)之前插入新元素(item) */
#define list_add_before(item, towhere) \
list_add(item,(towhere)->prev)
/* 删除某个元素 */
#define list_remove(item) do \
{ \
(item)->prev->next = (item)->next; \
(item)->next->prev = (item)->prev; \
} while(0)
/* 正向遍历链表中所有元素 */
#define list_for_each_item(item, head)\
for ((item) = (head)->next; (item) != (head); (item) = (item)->next)
/* 反向遍历链表中所有元素 */
#define list_for_each_item_rev(item, head) \
for ((item) = (head)->prev; (item) != (head); (item) = (item)->prev)
/* 根据本节点(item)获取节点所在结构体(type)的地址 */
/* 节点item地址(member的地址) - 该链表元素member在结构体中的偏移 */
#define list_entry(item, type, member) \
((type *)((char *)item - (char *)(&((type *)0)->member)))
/* 判断链表是否为空 */
#define list_is_empty(head) \
((head)->next == (head))
/* 获取指定位置上一元素 */
#define list_prev_item(item)\
((head)->prev)
#ifdef __cplusplus
}
#endif
#endif
testList.h
#ifndef _TESTLIST_H
#define _TESTLIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include "libList.h"
typedef struct tagInteger
{
int idx;
stList_Head stListHead;
}stInteger;
extern void testlist();
#ifdef __cplusplus
}
#endif
#endif
这种双向链表的特点在于:在需要链表管理的结构中定义一个链表节点变量,然后所有的操作都是针对这个链表节点进行的。在需要获取该结构时使用list_entry即可。
testList.c
#ifdef __cplusplus
extern "C" {
#endif
#include <malloc.h>
#include <stddef.h>
#include "stdafx.h"
#include "testList.h"
void testlist()
{
int i = 0;
stList_Head stListHead;
stList_Head *pstListHead= NULL;
stInteger *pstInteger = NULL;
stList_Head *pstTmpList = NULL;
/* 链表初始化 */
pstListHead = &stListHead;
list_init(pstListHead);
/* 生成节点并挂入链表 */
for(i = 0; i < 32; i++)
{
pstInteger = (stInteger *)malloc(sizeof(stInteger));
if (NULL == pstInteger)
{
printf("pstInteger malloc fail!");
return;
}
pstInteger->idx = 100 - i;
/* 挂到头结点之前 */
list_add_before(&pstInteger->stListHead, pstListHead);
/* 挂到头结点之后 */
//list_add(&pstInteger->stListHead, pstListHead);
}
/* 正向遍历链表中每一个元素并输出 */
list_for_each_item(pstTmpList, pstListHead)
{
if(NULL != pstTmpList)
{
pstInteger = list_entry(pstTmpList, stInteger, stListHead);
printf("%d ",pstInteger->idx);
}
}
return;
}
#ifdef __cplusplus
{
#endif
分享到:
相关推荐
第6章 嵌入式linux c语言基础——数组、指针与结构 168 6.1 数组 169 6.1.1 一维数组 169 6.1.2 字符串 172 6.1.3 二维数组 174 6.2 指针 175 6.2.1 指针的概念 175 6.2.2 指针变量的操作 ...
这是东南大学集成电路研究中心凌明老师的嵌入式高级C语言开发的课件,源码我一并上传
#### 用户点单功能实现了菜品动态添加的功能,通过将菜品信息以及菜品图片名称写入food.txt文件,应用菜品链表,实现菜单的动态更新。同时实现了菜单左右滑动翻页,单击菜品加一,长按菜品加一,左侧动态显示用户...
解压执行make可编译,基于ARM平台的电子相册实现源码,含带jpeg和freetype动态库,代码涉及大量指针操作、大量链表操作、framebuffer屏显、目录/文件检测、字体编解码、图片编解码操作,Makefile文件也可做其他...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 ...
2012-06-11 21:44 6,947,979 Linux内核完全注释V3.0书签版(带源码).rar 2012-06-11 21:31 11,599 MATLAB仿真程序OFDM程序.txt 2012-06-11 21:37 14,584,477 msdn for vb6.0简体中文版.zip 2012-06-11 21:02 12,288 ...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 1.1.2...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 1.1.2...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 1.1.2...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 1.1.2...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 1.1.2...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 1.1.2...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 1.1.2...
采用的案例均来源于作者实际开发工作,具有很好的实用价值,可以帮助读者在开发中进行参考或直接应用。 第1篇 开发基础 1 第1章 数字音视频开发技术基础 3 1.1 数字音视频基本概念 4 1.1.1 数字音频技术基础 4 ...