当前位置: 首页 > news >正文

优化网站关键词如何查询网站的域名注册

优化网站关键词,如何查询网站的域名注册,商业综合体,wordpress开启用户激活验证在之前的Linux系统编程中,学习了文件的打开;关闭;读写;进程;线程等概念.... 本节补充“Linux库概念 & 相关编程”,这是一个面试的重点! 分文件编程 在之前的学习中,面对较大的…

在之前的Linux系统编程中,学习了文件的打开;关闭;读写;进程;线程等概念....

本节补充“Linux库概念 & 相关编程”,这是一个面试的重点

分文件编程

在之前的学习中,面对较大的项目比如 STM32的小车 或 香橙派实现的智能垃圾桶 ,都使用了分文件编程的思路。

其 实现的核心思想就是:将功能性函数的实现单独写在其他的地方,在main函数中调用那些封装好的功能性函数。

这样做的好处是:

  • 分模块的编程思想:在实际工作中面对大型项目,可以让A完成串口开发;B完成网络开发,最后只需要他们提供h文件中的函数接口就可以在主函数中直接调用了,测试时发现哪部分有问题可以直接找负责的人,方便调试
  • 代码可移植性更强:因为分文件编程了,串口,网络,语音可能都被封装好了,那么后续如果其他项目需要这些功能就可以直接调用封装好的接口了,最多只需要微调
  • main函数更加精简:由于把功能性函数的实现步骤都封装到其他文件了,main函数就可以专注于项目的整体调用逻辑,使得整个main看起来更加清晰,逻辑通畅

具体步骤

  1. 将功能性函数名和具体实现步骤写在一个.c文件中
  2. 创建一个同名的.h文件,包含所有可能会被调用的函数原型去除函数体
  3. main中包含刚刚创建的.h文件
  4. main中调用被封装好的函数接口
  5. 使用gcc 编译所有相关的.c文件封装函数的.c文件main函数所在的.c文件
  • h文件的大概格式:
int add(int x, int y);
int min(int x, int y);
float div(int x, int y);
  • main函数调用h文件的格式:
#include <stdio.h>
#include "XXX.h" 

Q:为什么同样是调用头文件,有时候使用' <> ',而有时候使用' "" '呢?

A:使用' <> '时,gcc在编译时会去“/usr/include/”或“/usr/local/include/”下找这个头文件;而使用' "" '时,gcc则会优先从代码运行的当前路径去找这个头文件!如果找不到,才会再去“/usr/include/”或“/usr/local/include/”下找这个头文件。

Linux的库

分文件编程的好处已经在刚刚说到,但是实际工作中会出现这种情况:程序员允许别人可以调用他封装好的功能性函数,但是他不希望别人可以看到他具体实现的函数体。在这种情况下,就要引入Linux的库的概念了!

库(程序函数库)是一种可执行的二进制形式、就是将源代码转化为二进制格式,相当于进行了加密,别人可以使用库,但是看不到库中的内容。

库是别人写好的现有的,可以复用的代码,现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

程序函数库可分为3种类型:静态函数库(static libraries)、共享函数库(shared libraries)、动态加载函数库(dynamically loaded libraries):

  • 静态函数库:在程序执行前就加入到目标程序中的库, 文件后缀是.a 
  • 共享函数库:在程序执行时动态(临时)由目标程序去调用,共享函数库=动态函数库=共享对象库(Linux), 文件后缀是.so 
  • 动态加载函数库:本质上和共享函数库是一个东西,“动态加载数据库”是windows中的叫法,文件后缀是.dll

因此,对于Linux系统来说可以简单的将库分为 动态库 和 静态库

静态库和动态库的比较

静态数据库(libXXX.a
优点
  1. 运行快
  2. 发布程序无需提供静态库,因为已经在app中,移植方便
缺点
  1. 程序大
  2. 更新部署发布麻烦
动态数据库(libXXX.so
优点
  1. 程序小
  2. 升级简单
  3. 不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享(动态)库的实例
缺点
  1. 运行相对慢

  2. 需要提供依赖的动态库

静态库的制作(不太常用了)

制作步骤
  • 使用以下指令将.c文件生成.o文件
gcc a.c b.c -c
  • 使用以下指令将.o文件打包成.a库文件
ar rcs 静态库的名字 原材料
例:ar rcs libXXX.a a.o b.o

这两步完成后,就生成了.a库文件,此时实现功能函数的.c文件和.o文件对于程序运行就不必要了,使得main函数可以调用这个库的条件就是有.h和.a文件,此时代码执行者可以调用库但却无法得知库中函数具体的实现步骤了。

库的使用
gcc XXXXX.c -L 库文件所在目录 -lXXXX -o XXX
//-L:将-L之后跟着的目录作为第一个寻找库文件的目录,寻找的顺序是:-L之后跟着的目录 -->/lib-->/usr/lib-->/usr/local/lib
//-l(小写L):指定库的名字(去掉lib和.a)
//-o:指定生成的最终应用程序的名字

小插曲:gcc编译时“-I(大写i)” 和“-L"的区别:

  • -I(大写i):将-I之后跟着的目录作为第一个寻找头文件的目录,寻找的顺序是:-I之后跟着的目录-->/usr/include-->/usr/local/include
  • -L:将-L之后跟着的目录作为第一个寻找库文件的目录,寻找的顺序是:-L之后跟着的目录 -->/lib-->/usr/lib-->/usr/local/lib
  • 头文件和库文件的关系:库文件可以包含头文件,头文件不可以包含库文件,头文件可视,库文件不可视

由于之前提到过,静态库的优点之一是“发布程序无需提供静态库” ,所以编译完成后,就可以直接运行程序了,不需要任何后缀!

动态库的制作(更常用)

制作步骤
  • 使用以下指令生成动态库:
gcc -shared -fpic xxx.c -o libxxx.so
//-shared用来生成动态库
//-fpic选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码
库的使用

编译的语句其实和静态库相同:

gcc XXXXX.c -L 库文件所在目录 -lXXXX -o XXX
//-L:将-L之后跟着的目录作为第一个寻找库文件的目录,寻找的顺序是:-L之后跟着的目录 -->/lib-->/usr/lib-->/usr/local/lib
//-l(小写L):指定库的名字(去掉lib和.a)
//-o:指定生成的最终应用程序的名字

注意!虽然编译的语句相同,但是回顾动态库的缺点“需要提供依赖的动态库” ,所以编译完成后不能像使用静态库那样直接运行,这是因为动态库是程序运行中临时调用的,解决办法是将动态库拷贝到/usr/lib/下:

sudo cp libXXXX.so /usr/lib/

然后,再直接运行程序就可以了!

将动态库复制到/usr/lib//lib/下是因为程序执行时动态库的默认搜索路径就是/lib/usr/lib;那么如果可以指定动态库的搜索路径,就可以不需要将库复制了,这就是另一种方法:使用环境变量LD_LIBRARY_PATH指定动态库搜索路径

export LD_LIBRARY_PATH="动态库所在的绝对路径"

通过添加这个环境变量,也可以成功运行程序了,但是这样做有一个问题:这个环境变量是临时的,也就是说只有在当前窗口生效,如果此时通过SSH再连接一个窗口,又会找不到动态库了,解决办法是:写一个脚本start.sh:

export LD_LIBRARY_PATH="动态库所在的绝对路径"./可执行文件

然后给脚本一个可执行的权限:

chmod +x start.sh

其实这个脚本的作用就是在每次执行程序前设置一个临时的环境变量。

动态库的实操演示

首先在树莓派家目录下创建一个mjm_code文件夹,学习用的代码全放在这里面:

然后分别创建一个“test_main.c”和一个“test_func.c”来模拟main函数所在的C文件和封装功能函数的C文件:

test_main.c:

#include <stdio.h>
#include "test_func.h"int main()
{int a;int b;int ret;float ret1;printf("请输入第一个数\n");scanf("%d",&a);printf("请输入第二个数\n");scanf("%d",&b);printf("开始计算\n");ret = add(a,b);printf("相加为%d\n",ret);ret = min(a,b);printf("相减为%d\n",ret);ret = mul(a,b);printf("相乘为%d\n",ret);ret1 = div(a,b);printf("相除为%f\n",ret1);return 0;
}

test_func.c:

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

test_func.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);

然后尝试编译运行:

 

没有报错,程序正常运行,到此为止就是一个分文件编程的典型例子。

接下来,尝试将test_func.c做成一个动态库:(库名我这里叫“scalc”)

 gcc -shared -fpic test_func.c -o libscalc.so

 

 然后进行编译:(我生成了一个叫“calc”的可执行程序)

gcc test_main.c -L . -lscalc -o calc
//-L后的“.”代表当前路径

然后将生成的.so文件复制到usr/lib/下,并删除当前路径下的.so文件:

1. sudo cp libscalc.so /usr/lib/
2. rm libscalc.so //可以不删,删了是为了证明复制到/usr/lib下之后当前路径的.so就没啥用了

 最后尝试运行:

成功运行!此时程序的执行只依赖.h文件和.so文件了,执行者可以调用接口但并不能查看test_func.c中功能函数的具体实现,因为这个.c文件已经被制作成.so的库了。 ​​​​​​​

http://www.yayakq.cn/news/406739/

相关文章:

  • 贵州最好的网站建设推广公司哪家好微信怎么弄小程序卖东西
  • 网站建设推广关键词网络营销的途径有哪些
  • 做的好的商城网站设计如何在百度发布广告信息
  • 余姚做百度网站建设做外贸是用什么网站做
  • 高港区住房和城乡建设局网站创建网站服务器地址
  • 建网站那家好上海做网站的公司
  • 网站用什么程序做的wordpress最好用的采集插件
  • win2008做网站拓客渠道有哪些
  • 建设银行网站储蓄账户查询密码外贸网址
  • 网站建设运行关键词网站查询
  • 巴西网站后缀高端企业网站设计公司
  • 上海的建设网站首页wordpress如何设置付费后可见
  • wordpress google 字体 插件seo排名查询
  • 1688网站特色个人网站电商怎么做
  • 网站制作找云优化小米路由器建设网站
  • 厦门建设厅查询网站wordpress建站要钱么
  • 蚌埠北京网站建设江苏网站建设官网
  • 企业网站的建设目的有哪些常德外贸网站优化推广
  • 网站建设上海哪家公司好制作公司网站备案需要提供什么资料
  • 设计营销型网站域名seo推广是什么意思呢
  • 一站式建设网站射阳房产网
  • 做网站需要几步做网站如何用代码把字体变大
  • 提高网站排名的方法网站建设的公司哪家好
  • 优府网站建设乐清人才网官方网站
  • 长春网长春关键词排名站设计企业为什么上市
  • 网站建设专家网线制作视频
  • 织梦网站如何做二级导航栏中国互联网设计公司
  • 桂林生活网官方网站飓风算法受影响的网站
  • 电商网站首页怎么制作电商网站建设要多少钱
  • 做网站加手机app需要多少钱网站水印图片欣赏