Linux 下 简单动态库创建(以基本排序函数为例)

来源:互联网 发布:先帝知臣谨慎中考题 编辑:程序博客网 时间:2024/06/06 07:11

目的:将vs下写的常见的排序函数:冒泡排序,插入排序,二路归并排序,堆排序,选择排序,希尔排序,快速排序。放在Linux下做成一个动态库文件,方便以后调用。这里只介绍一种最基本的方法。

Linux系统:Ubuntu

文件准备:

初始文件夹:sort

                 - include  

                            - array.h  sort.h

                 - lib 

                 - src 

                          - heap_sort.c   merge_sort.c   select_sort.c  bubble_sort.c   insert_sort.c   quick_sort.c  shell_sort.c  array.c   test.c  

                 - bin

将windows下的文件复制到Linux下,有两种方式,一种用winscp软件,一种在虚拟机下安装vmware tools 然后直接复制粘贴即可。

注意:将vs下的文件复制到Linux下,如果文件中有中文字符,则在Linux下会出现乱码,因为windows下默认编码是gbk,而Linux下默认编码是utf-8,可以在Linux下

设置:root@ubuntu:/# vim ~/.vimrc

在vimrc中设置:set encoding=utf-8 fileencodings=usc-bom,utf-8,cp936

上面各种.c文件都是排序函数,include下是头文件,lib下准备放库文件,bin下放可执行文件。

各种函数代码:

array.h

#include<stdlib.h>#define N 10void produce_random_array(int array[], int n);void show_array(int array[], int n);#endif
sort.h
#ifndef _SORT_H#define _SORT_H#include<stdio.h>#include<stdlib.h>void bubble_sort(int array[], int n);void heap_adjust(int array[], int parent_node, int length);void heap_sort(int array[], int n);void insert_sort(int array[], int n);void merge(int array[], int begin_index, int mid_index, int end_index);void merge_sort(int array[], int n);void quick_sort(int array[], int begin, int end);void select_sort(int array[], int n);void shell_sort(int array[], int n);#endif
array.c
#include"array.h"void produce_random_array(int array[], int n){int i;srand(time(NULL));for (i = 0; i < n; i++){array[i] = rand() % 100;}}void show_array(int array[], int n){int i;for (i = 0; i < n; i++)printf("%-3d", array[i]);}

bubble_sort.c

#include"sort.h"void bubble_sort(int array[], int n){int i, j, temp;for (i = 0; i < n; i++){for (j = 0; j + 1<n - i; j++){if (array[j + 1] < array[j]){temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;}}}}
heap_sort.c
#include"sort.h"void heap_adjust(int array[], int parent_node, int length)//自上而下调整为大堆根(只调整一个结点){int child_node, temp;temp = array[parent_node];child_node = 2 * parent_node + 1;//数组下标是从0开始的while (child_node < length)//孩子结点下标小于数组长度{if (child_node < length - 1 && array[child_node] < array[child_node + 1])child_node++;//找到孩子结点中的最大值结点if (temp < array[child_node]){array[parent_node] = array[child_node];parent_node = child_node;child_node = 2 * parent_node + 1;}elsebreak;array[parent_node] = temp;}}/*调整结点函数,将parent_node 结点以下的调整为大堆根或者小堆根,实现自上而下调整,parent_node所表示的结点的值总比子树节点的值大或者小。*/void heap_sort(int array[], int n){int i, temp;for (i = n / 2 - 1; i >= 0; i--){heap_adjust(array, i, n);}//将初始无序堆建立为大堆根for (i = n - 1; i >= 1; i--){temp = array[0];array[0] = array[i];array[i] = temp;heap_adjust(array, 0, i);/*第一次建堆后,以后每次调整堆都是以parent_node=0为父节点,自上而下调整,然后将parent_node 与当前未排序数组的最后一位交换*/}}
insert_sort.c
#include"sort.h"void insert_sort(int array[], int n){int i, j, temp;for (i = 1; i < n; i++){temp = array[i];for (j = i - 1; j >= 0 && temp<array[j]; j--){array[j + 1] = array[j];}array[j + 1] = temp;}}
merge_sort.c
#include"sort.h"void merge(int array[], int begin_index, int mid_index, int end_index){int i = begin_index, j = mid_index + 1, k = 0;int *p = (int*)malloc(sizeof(int)*(end_index - begin_index + 1));/*malloc函数指向一个大小为sizeof(int)*(j-i+1)的整型数据空间,返回这个空间的首地址,指针p指向这个空间*/while (i <= mid_index&&j <= end_index){p[k++] = (array[i] <= array[j]) ? array[i++] : array[j++];}while (i <= mid_index)p[k++] = array[i++];while (j <= end_index)p[k++] = array[j++];for (k = 0, i = begin_index; i <= end_index; i++, k++)array[i] = p[k];free(p);p = 0; /*或者 p = NULL,释放p指向的内存后,将p指针赋值为0,避免p指针成为野指针*/}void merge_sort(int array[], int n){int i, j;for (i = 1; i < n; i = i * 2){for (j = 0; j + 2 * i < n - 1; j = j + 2 * i){merge(array, j, j + i - 1, j + 2 * i - 1);}if (j + i <= n - 1)merge(array, j, j + i - 1, n - 1);}}
quick_sort.c
#include"sort.h"void quick_sort(int array[], int begin, int end){int i, j, temp;if (begin< end){i = begin;j = end;temp = array[i];while (i < j){while (array[j]>temp&&i<j)j--;if (i<j)array[i++] = array[j];while (array[i] < temp&&i<j)i++;if (i<j)array[j--] = array[i];}if (i == j)array[i] = temp;quick_sort(array, begin, i - 1);quick_sort(array, i + 1, end);}}
select_sort.c
#include"sort.h"void select_sort(int array[], int n){int i, j, index_min, temp;for (i = 0; i < n; i++){index_min = i;for (j = i + 1; j < n; j++){if (array[j] < array[index_min])index_min = j;}if (index_min != i){temp = array[i];array[i] = array[index_min];array[index_min] = temp;}}}
shell_sort.c
#include"sort.h"void shell_sort(int array[], int n){int k, i, j, temp;for (k = n / 2; k>0; k = k / 2){for (i = k; i< n; i++){temp = array[i];for (j = i - k; j >= 0 && (temp<array[j]); j = j - k){array[j + k] = array[j];}array[j + k] = temp;}}}
test.c
#include"array.h"#include"sort.h"int main(int argc, char *argv[]){int array[N];produce_random_array(array, N);printf("原数组如下:\n");show_array(array, N);//冒泡排序printf("\n冒泡排序结果:\n");bubble_sort(array, N);show_array(array, N);//堆排序printf("\n堆排序结果:\n");heap_sort(array, N);show_array(array, N);//插入排序printf("\n插入排序结果:\n");insert_sort(array, N);show_array(array, N);//二路归并排序printf("\n二路归并排序结果:\n");merge_sort(array, N);show_array(array, N);//快速排序printf("\n快速排序结果:\n");quick_sort(array, 0, N - 1);show_array(array, N);//选择排序printf("\n选择排序结果:\n");select_sort(array, N);show_array(array, N);//希尔排序printf("\n希尔排序结果:\n");shell_sort(array, N);show_array(array, N);return 0;}

准备好sort文件,并将其放入Linux下后:

1.首先运行test.c文件,检查函数是否出错

    root@ubuntu: /sort# gcc -o ./bin/main.exe ./src/*.c  -I./include

    执行后,可以在bin文件夹中找到可执行文件main.exe

     root@ubuntu: /bin# ./main.exe

     程序运行结果:

     原数组如下:
     77 1  71 5  18 26 32 77 55 32
     冒泡排序:
     1  5  18 26 32 32 55 71 77 77
     堆排序:
    1  5  18 26 32 32 55 71 77 77
     插入排序:
    1  5  18 26 32 32 55 71 77 77
     二路归并排序:
     1  5  18 26 32 32 55 71 77 77
    快速排序:
    1  5  18 26 32 32 55 71 77 77
     选择排序:
     1  5  18 26 32 32 55 71 77 77
     希尔排序:
     1  5  18 26 32 32 55 71 77 77

2. 在Linux下将自己写的函数做成库,直接调用

    a. 预编译和编译,对包含头文件(#include)和宏定义(#include、#ifndef)等进行处理,生成.o文件

      root@ubuntu: /sort# gcc -fPIC -Wall  -c  ./src/array.c  -o ./lib/array.o  -I ./include

                                                                   .

                                                                   .

                                                                   .

     注释: -fPIC  表示生成使用相对地址的位置无关的目标代码。

                 -Wall  消除警告,即将警告也看成错误

                -I ./include  连接头文件(.h文件)注意是大写的I

      将所有.c文件都生成.o文件,当然除了test.c。

      完成上述步骤后,在lib目录看到.o 文件。

    b. 生成动态库文件,即.so 文件

       root@ubuntu:/sort/lib#  gcc -shared -o libmysort.so ./*.o

      注释:-shared 生成动态库文件 

                  动态库文件命名:libXXX.so  XXX表示自定义命名,lib是标准,.so是格式,还可以在后面加上版本号。

     执行命令后,在lib下生成 libmysort.so

   c. 生成动态库文件后,要保证程序运行时能够找到库文件,系统库文件默认查找是在/lib下,所以需要将libmysort.so复制到/lib下,64位Linux系统放在/lib64下不能搞混了。

       root@ubuntu:/sort/lib#  cp ./libmysort.so  /lib/

   d.调用库函数,要用到函数声明,而函数声明在头文件array.h和sort.h中,所以也要将头文件放在系统的默认头文件目录中。

      root@ubuntu:/include# cp ./array.h ./sort.h  /usr/include/sort/

     注释: sort是在usr/include 目录下新建的一个目录用来存放自己自定义的头文件。

   d. 执行程序,也就是利用libmysort.so  ,直接调用自己写的排序函数来运行程序。

      首先在一个随便目录test_sort下写个test001.c,简单调用各种排序函数。

      test001.c:

  1 #include<sort/array.h>  2 #include<sort/sort.h>  3 int main(int agrc,char *argv[])  4 {  5     int array[10];  6     produce_random_array(array,10);  7     printf("原数组如下\n");  8     show_array(array,10);  9     bubble_sort(array,10); 10     printf("\n数组冒泡排序如下:\n"); 11     show_array(array,10); 12     printf("\n"); 13     return 0; 14 }
注释:#include<sort/array.h>表示在默认的头文件文件夹include下的sort目录下查找.h文件

     root@ubuntu:/test_sort# gcc -o main  test001.c -lmysort

     执行完后,会在test_sort生成main

      root@ubuntu:/test_sort# ./main

     结果:

     原数组如下
      42 15 31 35 59 30 67 36 29 31
     数组冒泡排序如下:
     15 29 30 31 31 35 36 42 59 67

其实生成动态库文件,还有很多方法,这只是其中一种最基本也是最简单的方法。

0 0