注:转载请标明出处。联系方式:E-mail411239339@qq.com

写过C/C++的程序员都知道要想程序正确的编译通过,需要引用一些通用的头文件,如#include <stdio.h>,有时我们自己也写过好多具有独立功能通用的函数,那么我们怎么使用自己写好的通用函数库呢,下面我将以数据结构中我们常见的循环链表为例,一步一步讲解怎么建立自己的C库:

 

1.  首先在根目录下创建一个名叫mylib的目录

#mkdir /mylib

2.  在目录中建立如下文件

[root@chin mylib]# tree -T .

|-- Makefile

|-- cutil.h

|-- cycle.c

|-- list.h

`-- man

    其中cutil.h是通用头文件,所有其它定义的头文件都包含于其中。Cycle.c是创建循环链表的相关函数实现,list.h中是创建循环链表的函数声明。Man目录用于说明各函数的作用与用法,考虑到篇幅,本文中省略此步。

3.  各文件内容如下所示:

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 $(BIN) $^ $(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

 

4.  编译生成动态库libcutil.so

  #make&make install

5.  建立自己的工作目录/home/code/cycle

  #mkdir /home/code/cycle -p

6.  创建以下文件

  [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;

}

 

7.  编译并运行

[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

8.  总结

    最后运行程序后达到了我们预期的单循环链表的效果,如果以后需要再次拓展库函数,我们只需要的mylib目录下建立相应的.c.h文件,并把.h文件包含进cutil.h这个头文件中即可。这样如果我们在平时训练中写过一些通用的函数,就可以把它加入到我们自己的C库当中了。

    当然,以上所说的几步也只是一些简单的手段,如果考虑到不同平台之间的移植性就得做更多的#ifdef ...#define...#endif等成对的预处理了。OKEnjoy your programming!