函数库是为代码复用建立的,将同一类型,需要在不同的程序里使用的函数放置在一起,就组成了一个函数库。如 C 语言的标准库,它集合了开发者常用的函数。开发者自行编写的函数也可以组成函数库,通常称之为自定义函数库。C 语言的函数库以源代码的形式放在头文件里,较大的函数库可能会用到多个文件,因此涉及到编译的问题。本节将讨论用文件组成函数库的问题。

5.6.1 程序文件的大小

C 语言编译器允许分别编译,为每个文件生成以“.o”为后缀的目标文件,最后执行链接过程生成可执行文件。将一个程序放在一个大文件中,或者分拆成多个较小的文件,所得到的结果其实是相同的。编译器编译一个大文件比编译由这个大文件拆分而成的一系列小文件所花费的时间要长,对成员员来说,小文件更容易阅读和理解,所以应该把大文件拆分为一系列小文件编写。而且如果修改程序时只修改了其中一个文件,那么编译时也只需要重新编译修改过的文件,再执行连接过程生成可执行文件,这样能缩短程序编译的总时间。

5.6.2 分类组织文件

在开发大型程序时,很容易迷失某个具体功能点在源代码中的位置。如果在程序设计的早期预先估计程序的规模,将同一类型的函数放在同一个文件中,以有意义的名字为函数和文件命名,编写详细的注释,则可以最大程度避免该问题。如下例所示的多个文件。

(1)主程序文件 exercise.c:

#include <stdio.h>
#include "rate_compute.h" // 包含用户自定义的函数库 rate_compute.h int main()
{
...
simple_interest(); // 调用函数库 rate_compute.h 中的函数
compound_interest(); // 调用函数库 rate_compute.h 中的函数
...
}

(2)包含所有利率计算函数原型的头文件 rate_compute.h:

#ifndef RATE_COMPUTE_H_			// 判断是否未定义标识符 RATE_COMPUTE_H_
#define RATE_COMPUTE_H_ // 定义标识符 RATE_COMPUTE_H_ ...
float simple_interest(float rate, int day); // 定义函数原型
float compound_interest(float rate, int day);
...
#endif

(3)包含所有利率计算函数定义的头文件 rate_compute.c:

#include "rate_compute.h"		// 包含用户自定义的函数库 rate_compute.h
...
float simple_interest(float rate, int day) // 定义函数
{
... // 定义函数体
} float compound_interest(float rate, int day)
{
...
}
...

这种结构是 C 语言实际开发中经常使用的。主程序文件控制程序主要的流程,而具体功能实现放在其他文件中。与利率计算有关的函数说明放在头文件 rate_compute.h 内,该文件利用编译预处理命令判断自己是否已经被包含,如果没有则进行函数说明。这样可避免因多个文件相互包含时,函数被重复说明而出错。函数定义部分放在头文件配对的 rate_compute.c 文件内,两个文件名前部分相同。rate_compute.c 文件需要使用 #include 语句包含头文件 rate_compute.h,这样,当主程序文件也包含头文件 rate_compute.h,就可以使用这些函数。编译器会处理文件之间的连接问题。

5.6.3 函数库

函数库由一系列函数说明文件和函数定义文件所组成,使用时,将该文件包含在自己的程序文件内。例如需要使用输入输出函数时,可使用标准库内的 stdio.h 文件,需要使用数学函数时,可使用标准库内的 math.h 文件。

Linux 系统上有大量的函数库资源,根据 GPL 协议,这些函数库都能免费使用,并且可按照自己的需求修改。很多Linux 系统上的程序发布时,同时也提供了相应的函数库,以便开发者扩展该程序,或者借助该程序实现程序中某一功能。例如 Pidgin 是 Linux 系统上常用的多协议即时通讯软件,用户可使用 Pidgin 提供的libpurple 开发新的即时通信软件,或者让自己的程序具备即时通信功能。Linux 系统常用的 C 语言函数库如表 9.1 所示。

表 9.1 Linux 系统常用的 C 语言函数库

libdbus D-Bus 进程间通信机制函数库,用于两个应用程序相互联系和交互消息
libpthread POSIX 线程库,用于多线程通信
libthread Solaris 线程库,用于多线程通信
libnet 网络开发库,用于实现和封装了数据包的构造和发送过程
libcurl 客户端 url 传输库,用于数据下载和上传
libpq PostgreSQL 数据库接口,用于操作 PostgreSQL 数据库
GLib GTK+ 和 GNOME 的基础,提供了具备可移植性的数据结构
GTK+ 图形化用户界面构件库,用于开发图形界面
GStreamer GStreamer 多媒体框架函数库,用于开发多媒体播放程序
libgrade Grade 开发库,用于所见即所得方式的图形界面开发

Linux 系统一般将函数放置在 “/lib”和“/usr/lib”两个路径中,GCC 编译器在编译时会自动搜索这两个路径。在位于默认搜索路径之外的函数库,可在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径,或者在“/etc/ld.so.conf”文件中添加库的搜索路径。另外还可以直接将库文件全部复制到程序开发目录中,或者在编译时指定函数库路径。

pkgconfig 程序为配置函数库的路径提供了方便,它用于在编译时指定函数库的路径。

首先需要安装该软件,安装命令如下:

yum install pkgconfig

pkgconfig 可查看已安装的函数库和函数库的版本信息,命令为:

pkg-config --list-all

例如在开发使用 GLib 库的程序时,在编译命令加入参数 “`pkg-config --cflags --libsglib-2.0`”:

gcc -g `pkg-config --cflags --libs glib-2.0` glib_test.c -o glib_test.o

在 Eclipse 中,先用鼠标单击 Project Explorer 中对应的项目名称,选择 Project|Properties 命令打开该项目的属性对话框。然后在对话框左侧的列表框中选择 C/C++Build|Settings 命令打开设置选项卡,在设置选项卡内Tool Settings 列表中选择 GCC C Compiler|Miscellaneous 列表项,将编译参数“`pkg-config --cflags --libs glib-2.0`”加入在 Other flags 文本框原有的内容后。再在同一个列表框中,选择 GCC C Linker|Miscellaneous列表项,将上面的编译参数输入到 Linker flags 文本框原有的内容后。单击 OK 按钮保存。

注意:pkg-config 指令是由一对特殊的符号“`”包围,该符号对应的键盘按键通常位于 Esc键 下方。

【C语言入门教程】5.6 函数库和文件的更多相关文章

  1. Go语言入门教程(十)之函数

    Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...

  2. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

  3. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  4. 《JavaScript语言入门教程》记录整理:入门和数据类型

    目录 入门篇 js介绍 历史 基本语法 数据类型 概述 null 和 undefined 数值 字符串 对象 函数 数组 本系列基于阮一峰老师的<JavaScrip语言入门教程>或< ...

  5. 《JavaScript语言入门教程》记录整理:面向对象

    目录 面向对象编程 实例对象与 new 命令 this关键字 对象的继承 Object对象的方法 严格模式(strict mode) 本系列基于阮一峰老师的<JavaScrip语言入门教程> ...

  6. Linux pwn入门教程(10)——针对函数重定位流程的几种攻击

    作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解 ...

  7. C语言入门教程-(5)格式化输入输出

    1.输入和输出 在程序的使用中,我们经常可以看的这么一个场景:用户需要输入数据,经过程序运算,得到结果后输出.在C语言中,输入数据和输出数据都是由库函数完成的,通过语句来输入/输出. 2.格式化输出— ...

  8. 【C语言入门教程】目录/大纲

    第一章 C语言编程基础 1.1 基本程序结构 1.2 函数库 和 链接 1.3 C语言“32个”关键字 第二章 数据类型.运算符和表达式 2.1 数据类型(5种基本数据类型),聚合类型与修饰符 2.2 ...

  9. 智能合约语言 Solidity 教程系列3 - 函数类型

    Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...

  10. c语言该怎么入门?C语言入门教程(非常详细)

    C语言是一门面向过程的编译型语言,它的运行速度极快,仅次于汇编语言.C语言是计算机产业的核心语言,操作系统.硬件驱动.关键组件.数据库等都离不开C语言:不学习C语言,就不能了解计算机底层. 这套「C语 ...

随机推荐

  1. Spring 文件上传功能

    本篇文章,我们要来做一个Spring的文件上传功能: 1. 创建一个Maven的web工程,然后配置pom.xml文件,增加依赖: <dependency> <groupId> ...

  2. HTML5系列四(WebWorker、地理定位)

    WebWorker简单应用 先从一个简单例子说起,计算数值加法 <script> var worker = new Worker('sumCalculate.js'); worker.on ...

  3. 使用chrome查看页面元素的css样式

    使用chrome查看页面元素的css样式 我们在写页面的时候,可能总是不知道怎么回事,就发现某个元素出现了问题,但是不知道为什么会这样,这时候,就需要使用强大的chrome了!!! 举例说明: 1. ...

  4. Tomcat_Java Web_内存溢出总结

    在抛出内存溢出错误的时候,一般都会提示内存泄露的种类,一般也都是按照区域进行划分: 1. 堆(heap)内存泄漏java.lang.OutOfMemoryError: Javaheap space:大 ...

  5. web项目中的跨域问题解决方法

    一种是JSONP 一种是 CORS. 在客户端Javascript调用服务端接口的时候,如果需要支持跨域的话,需要服务端支持. JSONP的方式就是服务端对返回的值进行回调函数包装,他的优点是支持众多 ...

  6. 【原】jquery图片预览

    平时我们在做图片上传的时候,如果可以让用户选择图片的时候,看到图片的效果,那这样用户体验会好很多,因为用户可以就可以决定是否继续用这张图片,尤其是和ajaxuploadfile结合使用的时候,图片的预 ...

  7. glade2支持C++代码的输出(3)

    今天完成了glade-2生成configure.ac/Makefile.am等调整 代码为:cpp_out_4.patch.zip BaseObject类也做了一些小的调整:BaseObject.00 ...

  8. windows 修改hosts 脚本

    @echo off echo "请注意你的杀毒软件提示,一定要允许" echo. & pause @del C:\Windows\System32\drivers\etc\ ...

  9. 基本药目录sop

    http://db.yaozh.com/basicdir 基本药物 编辑 "基本药物"的概念, 由世界卫生组织于1977年提出,指的是能够满足基本医疗卫生需求,剂型适宜.保证供应. ...

  10. (新手向)基于Bootstrap的简单轮播图的手机实现

    个人电脑里存了不少适合手机欣赏的图片,但是放手机里看是件很占据资源的事.鉴于家里有一台电脑经常开着,正好用来做家庭局域网共享,于是笔者就设想通过一种比较简单环保的思路.通过手机访问电脑内的图片. 首先 ...