您的位置:首页 > 运维架构 > Linux

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

2015-05-18 16:04 435 查看
目的:将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 10
void 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;
}
else
break;
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
;
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
4000
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

其实生成动态库文件,还有很多方法,这只是其中一种最基本也是最简单的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息