函数库是为代码复用建立的,将同一类型,需要在不同的程序里使用的函数放置在一起,就组成了一个函数库。如 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. UEditor上传图片到七牛云储存(c#)

    我们的网站一般放在虚拟空间或者服务器上,图片如果存在本地目录,会占用很多空间和流量,还增加了负担,好的办法是把图片存放到云储存服务里面,平时用url去拿 云储存:普遍说又拍云和七牛比较好,看到七牛免费 ...

  2. AngularJs filter 过滤器

    Filter Ng里的过滤器. currency:把一个数字格式化成货币模式(如$1,234.56).当没有提供任何货币符号时,默认使用当前区域的符号. 使用: HTML:{{ currency_ex ...

  3. How to overcome “datetime.datetime not JSON serializable” in python?

    json.dumps(datetime.now) 意思是datetime.now不可json序列化,解决办法是转化成str或者加一个参数 cls=xxx 详细见: http://stackoverfl ...

  4. Mac下同时安装多个版本的JDK

    JDK8 GA之后,小伙伴们喜大普奔,纷纷跃跃欲试,想体验一下Java8的Lambda等新特性,可是目前Java企业级应用的主打版本还是JDK6, JDK7.因此,我需要在我的电脑上同时有JDK8,J ...

  5. 如何在Visual Studio 2013中使用Ribbon For WPF

    1.首先需要 下载Ribbon For WPF.目前最新的版本是Microsoft Ribbon for WPF October 2010. 下载 链接: https://www.microsoft. ...

  6. Linux tcpdump 命令详解

    简介用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据包的& ...

  7. CentOS7安装mysql5

    CentOS7的yum源中默认没有mysql. 1. 下载mysql的repo源 $ wget http://repo.mysql.com/mysql-community-release-el7-5. ...

  8. SVN服务器配置说明

    1.前 言 花了72小时,终于把 Subversion 初步掌握了.从一个连“什么是版本控制”都不知道的门外汉,到配置出精确至每目录访问的入门者,中间还卡了一天时间.其中费了许多气力,摸索实验了多次, ...

  9. 批处理学习:for语句详解【经典】

    大纲 一 前言 二 for语句的基本用法 三 for /f (delims.tokens.skip.eol.userbackq.变量延迟) 四 for /r (递归遍历) 五 for /d (遍历目录 ...

  10. Android学习笔记——ListView

    该工程的功能是实现在一个activity中显示一个列表 以下代码是MainActivity.java中的代码 package com.example.listview; import java.uti ...