写过C/C++的程序员都知道要想程序正确的编译通过,需要引用一些通用的头文件,如#include <stdio.h>,有时我们自己也写过好多具有独立功能通用的函数,那么我们怎么使用自己写好的通用函数库呢,下面我将以数据结构中我们常见的循环链表为例,一步一步讲解怎么建立自己的C库:
-
首先在根目录下创建一个名叫mylib的目录
mkdir /mylib
-
在目录中建立如下文件
[root@chin mylib]# tree -T . |-- Makefile |-- cutil.h |-- cycle.c |-- list.h `-- man
其中cutil.h是通用头文件,所有其它定义的头文件都包含于其中。Cycle.c是创建循环链表的相关函数实现,list.h中是创建循环链表的函数声明。Man目录用于说明各函数的作用与用法,考虑到篇幅,本文中省略此步。
-
各文件内容如下所示
1) Makefile内容
BIN = libcutil.so LDFLAGS = -lpthread CFLAGS += -g -Wall -shared -fPIC LIBS = -L . all:(BIN) OBJECT={patsubst %.c, %.o, {wildcard *.c}} .c.o: {CC} -o @ -c ? {CFLAGS}(BIN):{OBJECT} {CC} (CFLAGS) -o @ ^ (LDFLAGS) (LIBS) install: cp ./*.so /usr/lib .PHONY:clean clean: -rm *.o (BIN)
2) 下面是cycle.c的内容
#include "cutil.h" list create_list_head( void ) { list head = NULL; head = (list)malloc(sizeof *head); head->item = 1; return head; } void insert_cycle_node(list p,int num) { int i; list s; s = p; for(i = 2;i<= num ;i++) { s->next =(list)malloc(sizeof *s); s = s->next; s->item = i; } s->next = p; } void print_cycle_list(list p) { list s; s = p; int count = 1; while(s->next != p) { printf("The %dth Item value is:%d\n",count++,s->item); s = s->next; } printf("The %dth Item value is:%d\n",count,s->item); } void destroy_cycle_list(list p) { list s,ptmp; s = p; while(s->next != p) { ptmp = s; s = s->next; free(ptmp); } free(s); }
3) list.h内容如下:
#ifndef __LIST_H__ #define __LIST_H__ typedef struct _list *list; struct _list{ int item; list next; }; list create_list_head( void ); //创建链表头结点 void insert_cycle_node( list p,int num ); //插入循环链表结点 void print_cycle_list( list p ); //打印循环链表 void destroy_cycle_list( list p); //销毁循环链表 #endif
4) cutil.h内容如下:
#ifndef __CUTIL_H__ #define __CUTIL_H__ #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include "list.h" #endif
-
编译生成动态库
make && make install
将动态库拷贝到系统标准库路径下/lib或/usr/lib目录均可,不然后面运行程序的时候会报找不到动态库的错误。
-
建立自己的工作目录
mkdir /home/code/cycle -p
-
创建以下文件
[root@chin sort_list]# tree -T . |-- Makefile `-- cycle.c
编辑Makefile文件如下:
BIN = cycle CFLAGS = -g -Wall LDFLAGS = -lcutil INCLUDE = -I/mylib LIBS = -L /mylib all:(BIN) OBJECT={patsubst %.c, %.o, {wildcard *.c}} .c.o: {CC} -o @ -c ? {CFLAGS} {INCLUDE} (BIN):{OBJECT} {CC} -o @ ^ {INCLUDE} (LDFLAGS) (LIBS) .PHONY:clean clean: -rm *.o $(BIN)
编辑cycle.c内容如下:
#include "cutil.h" //以""引用的头文件,程序编译时会首先在当前目录下寻找此头文件,如果没找到将会去我们指定的路径中寻找。 int main(int argc,char *argv[]) { list phead; int n; printf("How many node do you want to create:"); scanf("%d",&n); phead = create_list_head(); //创建带头结点的链表 insert_cycle_node(phead,n); //插入循环链表结点 print_cycle_list(phead); //打印循环链表结点 destroy_cycle_list(phead); //释放链表 return 0; }
-
编译并运行
[root@chin sort_list]# make cc -o cycle.o -c cycle.c -g -Wall -I/mylib cc -o cycle cycle.o -I/mylib -lcutil -L /mylib [root@chin sort_list]# ./cycle How many node do you want to create:5 The 1th Item value is:1 The 2th Item value is:2 The 3th Item value is:3 The 4th Item value is:4 The 5th Item value is:5
-
总结
最后运行程序后达到了我们预期的单循环链表的效果,如果以后需要再次拓展库函数,我们只需要的mylib目录下建立相应的.c和.h文件,并把.h文件包含进cutil.h这个头文件中即可。这样如果我们在平时训练中写过一些通用的函数,就可以把它加入到我们自己的C库当中了。
当然,以上所说的几步也只是一些简单的手段,如果考虑到不同平台之间的移植性就得做更多的#ifdef ...#define...#endif等成对的预处理了。OK!Enjoy your programming!
- 微信扫码赞助
- 支付宝赞助
来自外部的引用: 1