嵌入式-C语言之库函数详解

上传人:ji****72 文档编号:46544687 上传时间:2018-06-27 格式:PDF 页数:9 大小:402.81KB
返回 下载 相关 举报
嵌入式-C语言之库函数详解_第1页
第1页 / 共9页
嵌入式-C语言之库函数详解_第2页
第2页 / 共9页
嵌入式-C语言之库函数详解_第3页
第3页 / 共9页
嵌入式-C语言之库函数详解_第4页
第4页 / 共9页
嵌入式-C语言之库函数详解_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《嵌入式-C语言之库函数详解》由会员分享,可在线阅读,更多相关《嵌入式-C语言之库函数详解(9页珍藏版)》请在金锄头文库上搜索。

1、C C 语言之库函数详解语言之库函数详解1 1.1.1、什么是函数库?、什么是函数库? (1)函数库本身不是 C 语言的一部分,是一些事先写好的函数的集合,给别人复 用。 (2)函数是模块化的,因此可以被复用。我们写好了一个函数,可以被反复使用。 也可以 A 写好了一个函数然后共享出来,当 B 有相同的需求时就不需自己写,直 接用 A 写好的这个函数即可。 如:我们常见输入函数 scanf ,输出函数 printf 就是我们所谓的库函数,也就 是标准输入输出库函数,在 stdio.h 的头文件中给出了相应的函数声明,我们 不用去管具体如何实现的,只需要调用就好。1 1.2.2、函数库的由来、函

2、数库的由来 最开始时没有函数库,每个人写程序都要从零开始自己写。时间长了早期的 程序员就积累了很多有用函数。早期的程序员经常参加行业聚会,在聚会上大家 互相交换各自的函数库, 后来程序员中的一些大神就提出把各自的函数收拢在一 起,然后经过校准和整理,最后形成了一份标准化的函数库,就是现在的标准的 函数库,譬如说 glibc。1 1.3.3、函数库的提供形式:静态链接库与动态链接库、函数库的提供形式:静态链接库与动态链接库 (1 1)静态链接库静态链接库 早期的函数共享都是以源代码的形式进行的。这种方式共享是最彻底的,后 来这种源码共享的方向就形成了我们现在的开源社区。但是这种方式有它的缺 点,

3、因为无法以商业化形式来发布函数库。 商业公司需要将自己的有用的函数库共享给别人,从中获取利润,但是又不 能给客户源代码。这时候的解决方案就是以库(主要有 2 种:静态库和动态库) 的形式来提供。 静态链接库是比较早出现的。 静态库其实就是商业公司将自己的函数库源代 码经过只编译不链接形成.o 的目标文件,然后用 ar 工具将.o 文件归档成.a 的 归档文件,这个.a 的归档文件就叫静态链接库文件。商业公司通过发布.a 库文 件和.h 头文件来提供静态库给客户使用;客户拿到.a 和.h 文件后,通过.h 头文 件得知库中的库函数的原型,然后在自己的.c 文件中直接调用这些库文件,在 链接的时候

4、链接器会去.a 文件中找到对应的.o 文件,链接后最终形成的可执行 程序。(2 2)动态链接库(共享库)动态链接库(共享库) 动态链接库比静态链接库出现的晚一些,其效率更高。现在我们一般都是使 用动态库。静态库在被链接形成可执行程序时,就已经把调用的库中的代码复制 进了可执行程序中,这种方式的问题是,太占空间。尤其是有多个应用程序都使 用了这个库函数时,导致在多个应用程序生成的可执行程序中,都各自复制了一 份该库函数的代码。当这些应用程序同时在内存中运行时,实际上在内存中同时 存在多个该库函数的副本,这样很浪费内存。 动态链接库做法不是将库函数的代码直接复制进可执行程序中,只是做个链接标记。然

5、后当应用程序在内存中执行时,运行时环境发现它调用了一个动态库 中的库函数时,会加载这个动态库到内存中,以后不管有多少个应用程序在同时 使用该库函数,该库函数在内存中只有一份。1 1.4.4、库函数的使用、库函数的使用 库函数的使用需要注意以下四点: 第一,包含相应的头文件; 第二,调用库函数时注意函数原型; (每个参数的意义、类型和返回值) 第三,有些库函数链接时需要使用-lxxx 的方式指定链接具体的库; 第四,如果是动态库,可能还需要使用-L 指定动态库的存放目录。 示例:hello.c命令行下执行:gcchello.c -o hello ls -l/默认以字节为单位显示。 显示 :-rw

6、xrwxr-x1 linux linux7159Apr3 19:54hello /hello 是 7159 字节命令行下执行:gcchello.c -static -o hello ls -l/默认以字节为单位显示。 显示:-rwxrwxr-x1 linux linux742801Apr3 19:58hello /hello 是 742801 字节使用-static 强制进行静态链接后,我们发现静态链接后的文件大小是之前 的 100 倍,这是因为使用静态链接时,由于库被直接复制到了代码中,因此可执 行文件大了非常多。默认情况下 gcc 都是使用动态链接库的,因此生成的可执行 文件小了很多。 如

7、图: 静态链接:动态链接:stdio.ahello 可执行文件大小:742801 字节hello.oinclude int main() printf(“hello worldn”); retrun 0; 静态链接在链接时,链接器会到.a 文件中找到被使用函数所在的.o 文件, 将其静态链接时直接复制库的内容,形成可执行文件。动态链接只是做个标记, 然后当应用程序在内存中执行时, 运行时环境发现它调用了一个动态库中的库函 数时,然后才会去加载这个动态库到内存中。 单一程序时,实际上它们所占用的内存的大小的一样的,当多个程序同时执 行的时候动态库的优势才显示出来。 如: 2 个 hello 可执

8、行文件同时执行的时候, 静态链接的库方式的hello 可执行文件会占用 2个stido.a+2个hello.o内存空 间。而动态链接库的方式只占用 2 个 hello.o+1 个 stdio.so。2.2.常见的库函数之字符串函数常见的库函数之字符串函数 2 2.1.1、什么是字符串、什么是字符串 字符串就是由多个字符在内存中连续分布组成的字符结构。 字符串的特点是 指定了开头(字符串的指针)和结尾(结尾固定为字符0) ,而没有指定长度 (长度由开头地址和结尾地址相减得到)2 2.2.2、为什么要讲字符串处理函数、为什么要讲字符串处理函数 函数库为什么要包含字符串处理函数?因为字符串处理的需求

9、是客观的, 所以从 很早开始人们就在写很多关于字符串处理的函数, 然后逐渐形成了现在的字符串 处理的函数库,面试时,常用字符串处理函数也是会被经常考到的要点。2 2. .3 3、manman 手册的使用手册的使用 在 linux 的 shell 命令下通过输入 man+部分号(数字)+对应的命令或函 数名的方式就可以查到对应的手册说明,当我们不加数字的时,man 手册按照它 本身的 section 的顺序寻找。 示例:$ man chmod 显示:CHMOD(1)User CommandsCHMOD(1)NAME chmod - change file mode bitsSYNOPSIS ch

10、mod OPTION. MODE,MODE. FILE. chmod OPTION. OCTAL-MODE FILE. chmod OPTION. -reference=RFILE FILE.stdio.sohello 可执行文件,执行到print 前,加载.so 文件hello大小:7159 字节DESCRIPTION 解析:CHMOD(1)这里面的 1 就是 section 编号; NAME 是这个命令的名字; SYNOPSIS 是简要描述; DESCRIPTIO 详细说明这个命令的用法; 注意: 许多命令和函数的名字是重复的,所以当我们使用 man 的时候最好加上手 册的部分号。2 2.

11、 .4 4、常用、常用的的字符串处理函数字符串处理函数 C 库中字符串处理函数的各种声明包含在 string.h 中,这个文件存放在 ubuntu 系统中在/usr/include 中,常见字符串处理函数有,memcpy 、memmove、 memove、 memset、 memcmp、 memchr、 strcpy、 strncpy、 strcat、 strncat、 strcmp、 strncmp、strdup、strndup、strchr、strstr、strtok 等。字符串处理函数所 在的头文件、函数原型及功能都可以通过 man 手册查阅得到。 示例:$ man 3 memcpy 查

12、询结果: MEMCPY(3)NAME memcpy - copy memory areaSYNOPSIS #include void *memcpy(void *dest, const void *src, size_t n);DESCRIPTION The memcpy() function copies n bytes from memory area src to memory area dest.The memory areas must not overlap.Use memmove(3) if the memory areas do overlap.RETURN VALUE The

13、 memcpy() function returns a pointer to dest.CONFORMING TO SVr4, 4.3BSD, C89, C99, POSIX.1-2001.SEE ALSO bcopy(3),memccpy(3),memmove(3),mempcpy(3),strcpy(3), strncpy(3), wmemcpy(3)COLOPHON This page is part of release 3.35 of the Linux man-pages project.解析:通过查看 man 手册我们可以清晰的了解到该函数应该如何使用,涉及函数 的信息如下:

14、头文件: #include 函数原型:void *memcpy(void *dest, const void *src, size_t n); 函数的功能:Thememcpy() function copies n bytes from memory area src to memory area dest.The memory areas must not overlap.Use memmove(3) if the memory areas do overlap. 函数的返回值:The memcpy() function returns a pointer to dest.3 3. .常见的

15、库函数之数学库函数常见的库函数之数学库函数 3 3.1.1、数学库函数、数学库函数 为了完成各种数学计算,如三角函数、指数、对数和双曲线函数等计算,常 常会用到数学库函数。 真正的数学运算函数的原型声明在: /usr/include/i386-linux-gnu/bits/mathcalls.h 中,不过实际使用数学库函 数的时候,只需要包含 math.h 头文件即可。3 3.2.2、计算开平方、计算开平方 通过 man 手册查阅我们得知: 头文件:#include 函数原型: double sqrt(double x); 返回值:double 类型。实用示例:注意:区分编译时警告/错误,和链

16、接时的错误:当我们把#include注释掉时,gcc 不带参数编译时: math.c:5:13: warning: incompatible implicit declaration of built-in function sqrt enabled bydefaultdouble b = sqrt(a); 这个警 告/错误告诉我们函数未声明。#include #include int main(void) double a = 16.0; double b = sqrt(a); printf(“b = %lf.n“, b);return 0; 当我们包含#include头文件,gcc 不带参数编译时: math.c:(.text+0x1b): undefined reference to sqrtcollect2: error: ld returned 1 exit status 链接时错误。为什么会出现这个链接错误呢? sqrt 函数有声明(声明就在 math.h 中)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号