sglib.h

SGLIB 翻译.md

SGLIB - A Simple Generic Library for C


SGLIB,一个简单用用的c语言库。

1.它是什么?

Sglib是一个定义用于操作公共数据结构的有用宏的库,该库目前提供通用实现:

  • 排序数组
  • 操作链表
  • 操作已排序的链接列表
  • 操作双链表
  • 操作红黑树
  • 操作哈希表

为每个数据结构提供了一组基本功能(宏)。它们包括元素的插入,删除,搜索和迭代遍历。此外,为每个数据结。

构提供附加(特定)功能,例如,列表的连接,反向或排序。

Sglib 提供算法, 而不是数据结构。Sglib 中实现的算法对用户数据类型类型进行操作, 例如, 列表宏对于包含指向同

一类型的指针的任何数据结构都是可操作的。

Sglib由一个没有任何二进制代码的头文件组成。为了使用它,只需将#include“sglib.h”放入源代码中。

该库采用 c 编程语言实现, 并为 c 程序员编写, 但它受标准模板库的自由启发。

虽然我希望保持该库尽可能简单,欢迎提出新的功能。目前, 队列、优先级队列、散列表和 AVL树(自平衡二

叉查找树)的实现正在开发中。

2.为什么它与现有的 C 库不同?

  • Sglib很一般。

Sglib不需要自己的数据结构。 您不需要将程序设计为从一开始就与Sglib一起使用。 您可以在项目开发的任何

阶段使用现有数据类型开始使用Sglib。

例如,假设您有一个程序处理由结构表示的历史事件列表:

struct event {
  int time;
  char *title;
  char *description;
  struct category *category;
  struct event *nextEvent;
};

假设您有按时间排序的此类事件列表。 您应该在此类列表中插入新事件。 首先,您需要定义一个比较器。 比较器

是宏或函数,当第一个参数大于,小于或等于第二个参数时,它们分别返回正值,负值或零值。 例如,以下宏是

我们需要的比较器:

#define CMP_EVENT(x,y) (x->time - y->time)

现在,您可以使用以下代码将新事件插入到列表中(同时保持列表已排序):

SGLIB_SORTED_LIST_ADD(struct event, theList, newEvent, CMP_EVENT, nextEvent);

该宏被扩展是将newEvent插入到List的正确位置的代码。

  • Sglib是通用的。

    Sglib在某种意义上是通用的,每个功能都按其运行的类型进行参数化。 它定义了独立于类型的算法。在 c++

中, 可以使用模板轻松完成此操作, 在 c 中这是通过预处理器实现的。无论宏参数是类型还是值, 预处理器都无关

要。但是, 由于预处理器是纯文本的, 不尊重基础编程语言, 因此需要额外的努力来防止宏被误用。

例如, 让我们用一个程序来定义由坐标表示的二维点数组。C 中相应的定义为:

struct point {
   int x;
   int y;
} thePointArray[SIZE];

和一个宏定义点的词典排序:

#define CMP_POINT(p1,p2) ((p1.x!=p2.x)?(p1.x-p2.x):(p1.y-p2.y))

在这种情况下,以下代码行使用堆排序对数组进行排序:

SGLIB_ARRAY_SINGLE_HEAP_SORT(struct point, thePointArray, SIZE, CMP_POINT);

请注意, 此实现中不涉及任何指针。

843/5000

  • Sglib很快。

    Sglib直接在您的数据结构上运行。 它不需要在其内部数据表示中存储额外的指针。 它既不包含任何分配,也

不包含内部数据结构。 此外,宏在编译时扩展,节省了与函数调用相关的开销。

  • Sglib独立于内存管理系统。

    Sglib不会创建/分配或销毁/释放任何数据。 它只会操作它们。 例如,操作平衡树的宏专门修改分配单元格

的“left_son”和“right_son”(或用户选择的任何名称)字段。 因此,Sglib完全独立于任何内存管理系统。 它从不

调用malloc或类似功能。 它非常适用于需要内存科学分配的项目。

  • Sglib很安全。

    宏被认为是BUG的来源,因为可以多次评估宏参数,并且在使用参数的范围内解析参数内的符号,而不是在调用宏解析。例如, 让我们来看看下面的宏:

#define LIST_LEN(type, list, result) {\
  int i;\
  type l;\
  for(i=0,l=list; l!=NULL; l=l->next, i++) ;\
  result = i;\
}

在这种情况下调用:

int ilistlen(ilist *l) {
  int res;
  LIST_LEN(ilist, l, res);
  return(res);
}

这里,符号l在列表LIST_LEN(struct ilist,l,res)中; 逻辑上预期将解析为函数ilistlen的形式参数。 但实际

上它被解析为由宏类型中的列表类型l; 内部定义的局部变量 l。 这通常会引发编译器警告使用未初始化的变量。

Sglib提供了两种避免此类问题的机制。

  • 首先,Sglib使用特定的命名约定。 宏内定义的所有变量都以_(下划线)开头和结尾。 由于在普通代码中使用此类名称是不常见的,因此可以降低冲突风险。 列表的上述宏计算长度将实现为:
#define LIST_LEN(type, list, result) { \
  int _i_; \
  type _l_; \
  for(_i_=0,_l_=(list); _l_!=NULL; _l_=_l_->next, _i_++) ; \
  (result) = _i_; \
}
  • 其次,Sglib不仅以宏的形式提供其所有功能,而且还以标准C函数的形式提供其所有功能。

在内部,我们将宏称为0级用户接口, 其功能为1级用户接口。1级接口为每个特定类型提供了合法的 C 函数,

可以从主程序调用这些函数, 而不必担心由于宏扩展而产生的不必要的麻烦。

实践中的1级接口意味着在程序开始时调用一个大型宏。 该宏按类型进行参数化,并为该类型生成所有可用函

数。 这些函数的名称将由前缀sglib_组成,后跟您的类型名称,并按其实现的操作名称结束。

例如调用:

SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(ilist, ilist_comparator, next);

扩展为函数定义, 如 :

sglib_ilist_len、sglib_ilist_sort、sglib_ilist_add、sglib_ilist_delete等。这些函数采用

ilist 类型的参数, 它们使用函数 (或宏)ilist_comparator来比较元素。您可以使用这些函数, 而不必担心宏扩

展。例如,上面的函数计算列表的长度将是:

int ilistlen(ilist *l) {
  int res;
  res = sglib_ilist_len(l);
  return(res);
}

请注意,调用SGLIB_DEFINE_SORTED_LIST_FUNCTIONS宏时几乎没有冲突的危险,因为此宏在顶级作用域

中调用,因为它仅使用非表达式参数。

3.为什么要这样做?

每个人都知道C预处理器可以用来模仿其他语言的通用性,每个人都认为这个想法是危险和丑陋的。我没有。

随着我编程实践中的经验, 我越来越频繁地使用参数化的类型的宏。 最后,我意识到我需要一个非常通用且设计良

好的通用库。 在网上进行研究之后,我发现只有`sys/queue.h头文件远远不是我需要的。 令我感到惊讶的是,在

C语言存在30年之后,在互联网时代,每个人都在为任何人做一切事情,没有人写过这样的库。 即使我相信有一

天我会找到一个类似的库,但我决定投入时间来创建Sglib。 我开始收集我为Xrefactory写的所有宏,给他们一个

统一的面孔。

与我大学的许多cake eaters(逸乐丧志的人,玩物丧志的人)相反,我相信Sglib背后的想法很好,因为我之前对

现代(和通用)编程语言的研究,以及我目前在C的重构浏览器上的工作。从以前的作品我知道许多通用结构是通

过某种形式的预处理器实现的。 在使用C重构浏览器时,我编写了自己的C预处理器。 在这项工作中,我已经意识

到预处理器的标准化程度以及它在当前ANSI标准中的精确程度。 因此,即使是非常先进的(你可能会说奇怪的)

预处理器结构也可以通过实现ANSI标准的编译器完全移植。

4.有没有可用的出版物或文件?

Sglib 附带了 HTML 格式的完整参考手册以及少量示例.

要在任何类型的文章中引用Sglib,请引用:

M. Vittek, P. Borovansky, P.E. Moreau: A Simple Generic Library for C, in Reuse of Off-the-Shelf Components: Proceedings of 9th International Conference on Software Reuse, Turin, pp. 423-426, 2006.

或者,以bibtex格式:

@Inproceedings{vittekBorovanskyMoreauTurin2006,
  author =       "Marian Vittek and Peter Borovansky and Pierre-Etienne Moreau",
  title =        "A Simple Generic Library for C",
  year =         "2006",
  pages =        "423-426",
  booktitle =    { Reuse of Off-the-Shelf Components: ,  Proceedings of 9th International Conference on Software Reuse, Tur
in, Italy},
  publisher =    {{Springer}}
}

5.在什么许可条件下?

基本上,我只关心您在使用Sglib时不从源代码中删除版权声明。

更确切地说:您可以在任何项目中使用Sglib或其衍生形式(在保留版权声明的条件下),无论是否商业,免

费。 特别是,您可以根据开源计划(Open Source Initiative)定义为开源许可证的任何许可条款使用Sglib(请参

http://www.opensource.org/)。 这包括最常见的开源许可证,例如BSD许可证和GNU GPL。

如果您需要在任何特定许可条件下使用sglib,请与作者联系。

保证

本源码“按原样”提供,不附带任何形式的明示或暗示保证,包括但不限于对适销性,特定用途的适用性或非侵

权性的暗示保证。

6.在哪里下载?

您可以从sourceforge站点下载sglib及其完整文档。

7.在哪里发布反馈?

您可以将您的反馈发布到sourceforge上托管的sglib邮件列表

 

 

 

 

 

 


100%(1)

0%(0)

发表评论

*