函数和函数库

来源:互联网 发布:淘宝申请退货在哪里 编辑:程序博客网 时间:2024/06/05 16:51

1.函数的本质
函数的目的就是实现模块化编程。说白了就是为了提供程序的可移植性。
(1)函数书写的一般原则:
第一:遵循一定格式。函数的返回类型、函数名、参数列表等。
第二:一个函数只做一件事:函数不能太长也不宜太短,原则是一个函数只做一件事情。
第三:传参不宜过多:在ARM体系下,传参不宜超过4个。如果传参确实需要多则考虑结构体打包
第四:尽量少碰全局变量:函数最好用传参返回值来和外部交换数据,不要用全局变量。
(2)函数三要素:定义、声明、调用
函数的定义就是函数体、函数声明是函数原型、函数调用就是使用函数
函数定义是函数的根本,函数定义中的函数名表示了这个函数在内存中的首地址,所以可以用函数名来调用执行这个函数(实质是指针解引用访问);函数定义中的函数体是函数的执行关键,函数将来执行时主要就是执行函数体。所以一个函数没有定义就是无基之塔。
函数声明的主要作用是告诉编译器函数的原型
函数调用就是调用执行一个函数。

2.递归函数、
(1)什么是递归函数:
①递归函数就是函数中调用了自己本身这个函数的函数。
②递归函数和循环的区别。递归不等于循环
③递归函数解决问题的典型就是:求阶乘、求斐波那契数列
(2)使用递归函数的原则:收敛性、栈溢出
收敛性就是说:递归函数必须有一个终止递归的条件。当每次这个函数被执行时,我们判断一个条件决定是否继续递归,这个条件最终必须能够被满足。如果没有递归终止条件或者这个条件永远不能被满足,则这个递归没有收敛性,这个递归最终要失败。
因为递归是占用栈内存的,每次递归调用都会消耗一些栈内存。因此必须在栈内存耗尽之前递归收敛(终止),否则就会栈溢出。

3.函数库
函数库就是一些事先写好的函数的集合,给别人复用。
(1)静态链接库:
静态库其实就是商业公司将自己的函数库源代码经过只编译不连接形成.o的目标文件,然后用ar工具将.o文件归档成.a的归档文件(.a的归档文件又叫静态链接库文件)。商业公司通过发布.a库文件和.h头文件来提供静态库给客户使用;客户拿到.a和.h文件后,通过.h头文件得知库中的库函数的原型,然后在自己的.c文件中直接调用这些库文件,在连接的时候链接器会去.a文件中拿出被调用的那个函数的编译后的.o二进制代码段链接进去形成最终的可执行程序。
(2)动态链接库:
动态链接库本身不将库函数的代码段链接入可执行程序,只是做个标记。然后当应用程序在内存中执行时,运行时环境发现它调用了一个动态库中的库函数时,会去加载这个动态库到内存中,然后以后不管有多少个应用程序去调用这个库中的函数都会跳转到第一次加载的地方去执行(不会重复加载)。

4.自己制作静态链接库并使用
(1)第一步:自己制作静态链接库
首先使用gcc -c只编译不连接,生成.o文件;然后使用ar工具进行打包成.a归档文件
库名不能随便乱起,一般是lib+库名称,后缀名是.a表示是一个归档文件
注意:制作出来了静态库之后,发布时需要发布.a文件和.h文件。
(2)第二步:使用静态链接库
把.a和.h都放在我引用的文件夹下,然后在.c文件中包含库的.h,然后直接使用库函数。
编译方法:gcc test.c -o test -laston -L.
静态链接库中的使用方法:
all:
gcc aston.c -o aston.o -c
ar -rc libaston.a aston.o

5.自己制作动态链接库并使用
(1)动态链接库的后缀名是.so(对应windows系统中的dll),静态库的扩展名是.a
(2)第一步:创建一个动态链接库。
gcc aston.c -o aston.o -c -fPIC
gcc -o libaston.so aston.o -shared
-fPIC是位置无关码,-shared是按照共享库的方式来链接。
注意:做库的人给用库的人发布库时,发布libxxx.so和xxx.h即可。
(3)第二步:使用自己创建的共享库。
编译方法:gcc test.c -o test -laston -L.
但是运行出错,报错信息:
error while loading shared libraries: libaston.so: cannot open shared object file: No such file or directory
错误原因:动态链接库运行时需要被加载(运行时环境在执行test程序的时候发现他动态链接了libaston.so,于是乎会去固定目录尝试加载libaston.so,如果加载失败则会打印以上错误信息。)
解决方法一:
将libaston.so放到固定目录下就可以了,这个固定目录一般是/usr/lib目录。
cp libaston.so /usr/lib即可
解决方法二:使用环境变量LD_LIBRARY_PATH。操作系统在加载固定目录/usr/lib之前,会先去LD_LIBRARY_PATH这个环境变量所指定的目录下去寻找,如果找到就不用去/usr/lib下面找了,如果没找到再去/usr/lib下面找。所以解决方案就是将libaston.so所在的目录导出到环境变量LD_LIBRARY_PATH中即可。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/hgfs/Winshare/s5pv210/AdvancedC/4.6.PreprocessFunction/4.6.12.sharedobject.c/sotest

参考:http://www.zhulaoshi.org/

0 0
原创粉丝点击