1、编程案例
好处:分模块的编程思想,①功能责任划分清楚,②方便调试,③主程序简洁
网络a,超声波b,电机c
无分文件演示(代码冗杂)
orangepi@orangepizero2:~/sub_file$ vi calculatorT.c
orangepi@orangepizero2:~/sub_file$ gcc calculatorT.c
orangepi@orangepizero2:~/sub_file$ ./a.out
请输入数1:
12
请输入数2:
13
12+13=25
12-13=-1
12*13=156
12/13=0.923077
orangepi@orangepizero2:~/sub_file$ cat calculatorT.c
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int min(int a,int b)
{
return a-b;
}
int mul(int a,int b)
{
return a*b;
}
float div(int a,int b)
{
return (float)a/b;
}
int main()
{
int data1;
int data2;
int ret;
float retfloat;
printf("请输入数1:\n");
scanf("%d",&data1);
printf("请输入数2:\n");
scanf("%d",&data2);
ret=add(data1,data2);
printf("%d+%d=%d\n",data1,data2,ret);
ret=min(data1,data2);
printf("%d-%d=%d\n",data1,data2,ret);
ret=mul(data1,data2);
printf("%d*%d=%d\n",data1,data2,ret);
retfloat=div(data1,data2);
printf("%d/%d=%f\n",data1,data2,retfloat);
return 0;
}
有分文件代码:
orangepi@orangepizero2:~/sub_file$ vi calcufuncs.c
orangepi@orangepizero2:~/sub_file$ vi calcufuncs.h
orangepi@orangepizero2:~/sub_file$ vi calculatorT.c
orangepi@orangepizero2:~/sub_file$ gcc calculatorT.c calcufuncs.c
orangepi@orangepizero2:~/sub_file$ ./a.out
请输入数1:
12
请输入数2:
13
12+13=25
12-13=-1
12*13=156
12/13=0.923077
orangepi@orangepizero2:~/sub_file$ cat calcufuncs.c
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int min(int a,int b)
{
return a-b;
}
int mul(int a,int b)
{
return a*b;
}
float div(int a,int b)
{
return (float)a/b;
}
orangepi@orangepizero2:~/sub_file$ cat calcufuncs.h
int add(int a,int b);
int min(int a,int b);
int mul(int a,int b);
float div(int a,int b);
orangepi@orangepizero2:~/sub_file$ cat calculatorT.c
#include <stdio.h>
#include "calcufuncs.h"
int main()
{
int data1;
int data2;
int ret;
float retfloat;
printf("请输入数1:\n");
scanf("%d",&data1);
printf("请输入数2:\n");
scanf("%d",&data2);
ret=add(data1,data2);
printf("%d+%d=%d\n",data1,data2,ret);
ret=min(data1,data2);
printf("%d-%d=%d\n",data1,data2,ret);
ret=mul(data1,data2);
printf("%d*%d=%d\n",data1,data2,ret);
retfloat=div(data1,data2);
printf("%d/%d=%f\n",data1,data2,retfloat);
return 0;
}
2、库
使用GNU的工具在linux下创建自己的程序函数库
静态函数库:执行程序前(编译)就加入到目标程序中
优点:运行快,一直方便
缺点:程序太大,更新部署,发布麻烦
动态加载库:在程序执行时动态(临时)由目标程序去调用。同共享函数库是一个东西(在linux上叫共享对象库,文件后缀是.so,windows上叫动态加载函数库,文件后缀是.dll)
静态库 | 动态库 | |
优点 | 1、静态库被打包到应用程序中加载速度快 2、发布程序无需提供静态库,因为已经在app中,移植方便 | 1、链接时不复制,程序运行时由系统动态加载到内存,供程序使用,系统只加载一次,多个程序可以共用,节省内存 2、程序升级简单,因为app里没有库的源代码,升级之后只要库的名字不变,函数名以及参数不变,只是实现做了优化,就能加载成功 |
缺点 | 1、链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝 更新、部署、发布麻烦 | 1、加载速度慢 2、发布程序需要提供依赖的动态库 |
共享函数库
3、静态库的制作&使用
静态库的制作:格式xxx.a
①gcc xxx.c -c:生成xxx.o文件
②ar rcs xxx.a xxx.o:生成xxx.a静态库文件
//第一步,生成.o文件
orangepi@orangepizero2:~/sub_file$ gcc calcufuncs.c -c
orangepi@orangepizero2:~/sub_file$ ls
a.out calcufuncs.c calcufuncs.h calcufuncs.o calculatorT.c
//第二部,生成.a文件
orangepi@orangepizero2:~/sub_file$ ar rcs libcalcufuncs.a calcufuncs.o
orangepi@orangepizero2:~/sub_file$ ls
a.out calcufuncs.c calcufuncs.h calcufuncs.o calculatorT.c libcalcufuncs.a
静态库的使用:
gcc 主文件.c -lxxx -L ./ -o xxxx
-lxxx:-l是指定要用的静态库,库名要砍头去尾
-L :告诉gcc编译器-L制定的路径去找静态库(默认是从/usr/lib /usr/local/lib去找)
orangepi@orangepizero2:~/sub_file$ gcc calculatorT.c -lcalcufuncs -L ./ -o test
orangepi@orangepizero2:~/sub_file$ ls
a.out calcufuncs.c calcufuncs.h calcufuncs.o calculatorT.c libcalcufuncs.a test
orangepi@orangepizero2:~/sub_file$ ./test
请输入数1:
12
请输入数2:
13
12+13=25
12-13=-1
12*13=156
12/13=0.923077
4、动态库的制作&使用
动态库的制作:
①gcc -shared -fpic xxx.c -o libxxx.so
-shared:指定生成动态库
-fpic:标准(fpic选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码)
orangepi@orangepizero2:~/sub_file$ gcc -shared -fpic calcufuncs.c -o libcalcufuncs.so
orangepi@orangepizero2:~/sub_file$ ls
a.out calcufuncs.h calculatorT.c libcalcufuncs.so
calcufuncs.c calcufuncs.o libcalcufuncs.a test
动态库的使用:
①sudo cp 动态库名.so /usr/lib/
需要将动态库放到/usr/lib/文件夹下,编译运行的时候会到该文件夹下链接该动态库
orangepi@orangepizero2:~/sub_file$ sudo cp libcalcufuncs.so /usr/lib/
gcc 主文件.c -lxxx -L ./
./a.out:运行代码
与静态库的编译使用是一样的,后边加-o 文件名:生成可执行文件
//新建文件夹添加文件:
orangepi@orangepizero2:~/sub_file$ mkdir dongtai
orangepi@orangepizero2:~/sub_file$ ls
a.out calcufuncs.h calculatorT.c libcalcufuncs.a test
calcufuncs.c calcufuncs.o dongtai libcalcufuncs.so
orangepi@orangepizero2:~/sub_file/dongtai$ cp /home/orangepi/sub_file/calculatorT.c .
orangepi@orangepizero2:~/sub_file/dongtai$ ls
calculatorT.c
orangepi@orangepizero2:~/sub_file/dongtai$ gcc calculatorT.c -lcalcufuncs
calculatorT.c:2:10: fatal error: calcufuncs.h: No such file or directory
#include "calcufuncs.h"
^~~~~~~~~~~~~~
compilation terminated.
orangepi@orangepizero2:~/sub_file/dongtai$ cp /home/orangepi/sub_file/calcufuncs.h .
orangepi@orangepizero2:~/sub_file/dongtai$ ls
calcufuncs.h calculatorT.c
//编译运行
orangepi@orangepizero2:~/sub_file/dongtai$ gcc calculatorT.c -lcalcufuncs
orangepi@orangepizero2:~/sub_file/dongtai$ ls
a.out calcufuncs.h calculatorT.c
orangepi@orangepizero2:~/sub_file/dongtai$ ./a.out
请输入数1:
12
请输入数2:
13
12+13=25
12-13=-1
12*13=156
12/13=0.923077
②也可以用shell脚本运行一段临时的代码(export临时指定动态库的位置,环境变量)
将.so文件位置设置为环境变量位置
export LD_LIBRARY_PATH="/home/orangepi/sub_file/"
gcc 主文件.c -lxxx -L ./ -o test2:编译生成可执行文件
orangepi@orangepizero2:~/sub_file/dongtai$ export LD_LIBRARY_PATH="/home/orangepi/sub_file" orangepi@orangepizero2:~/sub_file/dongtai$ cd .. orangepi@orangepizero2:~/sub_file$ ls a.out calcufuncs.h calculatorT.c libcalcufuncs.a test calcufuncs.c calcufuncs.o dongtai libcalcufuncs.so orangepi@orangepizero2:~/sub_file$ gcc calculatorT.c -lcalcufuncs -L ./ -o test2 orangepi@orangepizero2:~/sub_file$ ls a.out calcufuncs.h calculatorT.c libcalcufuncs.a test calcufuncs.c calcufuncs.o dongtai libcalcufuncs.so test2 orangepi@orangepizero2:~/sub_file$ ./test2 请输入数1: 12 请输入数2: 13 12+13=25 12-13=-1 12*13=156 12/13=0.923077
shell脚本运行
orangepi@orangepizero2:~/sub_file$ vi start.sh orangepi@orangepizero2:~/sub_file$ chmod +x start.sh orangepi@orangepizero2:~/sub_file$ ./start.sh 请输入数1: 12 请输入数2: 13 12+13=25 12-13=-1 12*13=156 12/13=0.923077 orangepi@orangepizero2:~/sub_file$ ls a.out calcufuncs.h calculatorT.c libcalcufuncs.a start.sh test2 calcufuncs.c calcufuncs.o dongtai libcalcufuncs.so test orangepi@orangepizero2:~/sub_file$ cat start.sh export LD_LIBRARY_PATH="/home/orangepi/sub_file" ./test2