2024年6月8日发(作者:)

b

n

c

.

w

w

Linux下C语言编程入门教程

w

t

e

n

.

t

k

e

o

n

o

.

b

k

n

o

c

.

w

w

w

t

e

n

.

t

k

e

o

n

o

.

b

k

n

o

c

o

.

b

w

n

w

c

w

.

t

e

n

.

t

k

e

o

n

o

.

b

k

n

o

c

o

.

b

w

n

w

c

w

.

w

w

w

t

k

e

o

n

o

.

b

k

n

o

c

o

.

b

w

n

w

c

w

.

w

w

w

t

e

n

.

k

o

c

o

.

b

w

n

w

c

w

.

w

w

w

t

e

n

.

k

o

o

内容提要:本文是Linux下C语言编程入门教程。主要介绍了Linux的发展与特点、C语言的

基础知识、Linux程序设计基础知识及其下C语言编程环境、Linux程序设计的特点及其下C语言

编程风格等。

关键字:Linux、C语言、vi、GCC、GNU make、GDB

引言:Linux作为一个优秀的操作系统,一项非常重要的功能就是支持系统调用尤其是支持C

语言的系统调用功能十分的方便、快捷。C语言具有高速、灵活、简洁、可移植性好等特点,从而

很快成为了世界上最受欢迎的编程语言之一。

正文:

k

o

o

1 Linux的发展和特点

Linux最初是专门为基于Intel处理器的个人计算机而设计的。Linux的前身是赫尔辛基大学

(University of Helsinki)一位名叫Linus Torvald的计算机科学系学生的个人项目。Linus把Linux建

立在一个基于PC机上运行的、缩小型的、名为Minux的UNIX基础之上,Minux本身具有UNIX的

各种特性,这使得以Minux做参照而产生的Linux继承并更突出了UNIX的各种优良特性。当时Linus

Torvold通过USENET(新闻组)宣布了Linux是一个免费的系统,并指出它主要在x86电脑上使用,

希望大家一起来将它完善,并将源代码放到了芬兰的FTP站点上供人免费下载。本来他想把这个系统

称为freax,可是FTP的工作人员认为这是Linus的Minux,就用Linux这个子目录来存放,于是它就

成了“Linux”。这时的Linux只有核心程序(内核),还不能称作是完整的系统,不过由于许多专业

用户(主要是程序员)自愿地开发它的应用程序,并借助Internet拿出来让大家一起修改一起完善,

所以它的周边的程序也越来越多,功能也越来越强大,Linux本身也就这样逐渐发展壮大起来。

近年来,Linux操作系统得到了迅猛地发展,在短短的几年之内就包含了UNIX的全部功能和

特性,在中高端服务器上得到了广泛的应用,国际上很多有名的硬、软件厂商都与之结盟、捆绑,

将之用作自己的操作系统。Linux操作系统得到了非常迅猛地发展,这与Linux具有的良好特性是

分不开的。

Linux操作系统的特点可总结为以下几点:

1. 自由软件

Linux项目从一开始就与GNU项目紧密结合起来,它的许多重要组成部分直接来自GNU项目。

Linux可以说是作为开放源码的自由软件的代表,便于定制和再开发。在遵从GPL版权协议的条件

下,各部门、企业、单位或个人就可以免费得到Linux源程序,并根据自己的实际需要和使用环境

对Linux系统进行裁剪、扩充、修改,再开发和发布程序的源码,并公布在Internet上。这样就激

发了世界范围内热衷于计算机事业的人们的创造力。通过Internet,这一软件的传播和使用迅速扩大。

因为Linux操作系统可以从互联网上很方便地免费下载,这样就可以省下购买Windows操作系统的

一笔不小的资金(正版Windows很昂贵)。且由于可以得到Linux的源码,所以操作系统的内部逻

辑是可见的,这样就可以根据源码准确地查明故障产生的原因,及时采取相应对策。

2. 开放性

开放性是指系统遵循世界标准规范,特别是遵循开放系统互连(OSI)国际标准。凡遵循国际

标准所开发的硬件和软件,都能彼此兼容,可方便地实现互连。

3. 多用户

系统资源可以被不同用户各自拥有使用,即每个用户对自己的资源(例如:文件、设备)有特定

的权限,互不影响,允许多个用户从相同或不同的终端上同时使用同一台计算机。

4. 多任务

它是指计算机允许多个程序同时执行,而且各个程序的运行互相独立。Linux系统调度每一个

进程,平等地访问微处理器。由于CPU的处理速度非常快,其结果是,启动的应用程序看起来好像

※ 1 ※

o

t

e

n

k

.

在并行运行。事实上,从处理器执行一个应用程序中的一组指令到Linux调度微处理器再次运行这

个程序之间只有很短的时间延迟,用户是感觉不出来的。Linux充分利用了X86CPU的任务切换机

制,实现了真正多任务、多用户环境,允许多个用户同时执行不同的程序,并且可以给紧急任务以

较高的优先级。

5. 与UNIX有良好的兼容性

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

Linux是从一个比较成熟的操作系统UNIX发展而来的,UNIX上的绝大多数命令都可以在Linux

里找到并有所加强。可以认为它是UNIX系统的一个变种,因而UNIX的优良特点,如可靠性、稳

定性以及强大的网络功能,强大的数据库支持能力以及良好的开放性等都在Linux上一一体现出来。

且在Linux的发展过程中,Linux的用户能大大地从UNIX团体贡献中获利,它能直接获得UNIX相

关的支持和帮助。现在,Linux已成为具有全部UNIX特征、完全符合POSIX标准的操作系统。POSIX

是基于UNIX的第一个操作系统簇国际标准,该标准最初由IEEE开发,部分已经被ISO接受为国

际标准。POSIX.1和POSIX.2分别定义了POSIX兼容操作系统的C语言系统接口以及shell和工具

标准。这两个标准是通常提到的标准。Linux遵循这一标准使得UNIX下许多应用程序可以很容易

地移植到Linux下,相反也是这样。所有UNIX的主要功能都有相应的Linux工具和实用程序。对

.

c

o

o

b

n

于UNIX System V来说,其软件程序源码在Linux上重新编译之后就可以运行;而对于BSD UNIX,

系统。

Linux系统上使用的命令多数都与UNIX命令在名称、格式、功能上相同。

6. 性能和稳定性好

它的可执行文件可以直接在Linux环境下运行。所以,Linux实际上就是一个完整的UNIX类操作

t

e

n

k

.

w

w

w

b

n

c

.

c

.

w

w

w

在相同的硬件环境下,Linux可以像其他优秀的操作系统那样运行,提供各种高性能的服务,

可以作为中小型ISP或Web服务器工作平台。Linux可以运行在386以上及各种RISC体系结构机

器上。Linux最早诞生于微机环境,一系列版本都充分利用了X86CPU的任务切换能力,使X86CPU

的效能发挥得淋漓尽致,而这一点连Windows都没有做到。Linux能运行在笔记本电脑、PC、工作

站,甚至巨型机上,而且几乎能在所有主要CPU芯片搭建的体系结构上运行(包括Intel/AMD及

HP-PA、MIPS、PowerPC、UltraSPARC、ALPHA等RISC芯片),其性能远远超过了Windows NT

操作系统目前所能达到的水平。

7. 可靠的系统安全

Linux上包含了大量网络管理、网络服务等方面的工具,用户可利用它建立起高效和稳定的防

火墙、路由器、工作站、Intranet服务器及WWW服务器。Linux还包括了大量系统管理软件、网络

分析软件、网络安全软件等。由于Linux源码是公开的,所以可消除系统中是否有“后门”的疑虑。

这对于关键部门、关键应用来说是至关重要的。Linux采取了许多安全技术措施,包括对读、写进

行权限控制、带保护的子系统、审计跟踪、核心授权等,这为网络多用户环境中的用户提供了必要

的安全保障。

8. 可移植性好

可移植性是指代码从一种体系结构移植到另外一种体系结构上的方便程度。Linux是一个可移

植性非常好的操作系统,它广泛支持了许多不同体系结构的计算机,能够在从微型计算机到大型计

算机的任何环境中和任何平台上运行,包括Intel、AMD、ARM、Mips等。可移植性让运行Linux

的不同计算机平台可以和其他任何机器进行准确而有效的通信,不需要另外增加特殊昂贵的通信接

口。

9. 多种用户界面

主要有命令接口、系统调用和图形界面。Linux的传统用户界面是基于文本的命令行界面,即

shell

,它既可以联机使用,又可存在文件上脱机使用。shell有很强的程序设计能力,用户可方便地

用它编制程序,从而为用户扩充系统功能提供了更高级的手段。可编程Shell是指将多条命令组合

在一起,形成一个Shell程序,这个程序可以单独运行,也可以与其他程序同时运行。系统调用给

用户提供编程时使用的界面。用户可以在编程时直接使用系统提供的系统调用命令。系统通过这个

界面为用户程序提供低级、高效率的服务。Linux还为用户提供了丰富的图形用户界面,如GNOME、

KDE等。它利用鼠标、菜单、窗口、滚动条等设施,给用户呈现一个直观、易操作、交互性强的友

※ 2 ※

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

好的图形化界面。Linux的X-Window可以做MS Windows下的所有事情,而且更有趣、更丰富,

用户甚至可以在几种不同风格的窗口之间来回切换。

10. 支持多种文件系统

Linux可以支持十多种文件系统类型:JFS、ReiserFS、ext、ext2、ext3、ISO9660、XFS、Minx、

MSDOS、UMSDOS、VFAT、NTFS、HPFS、NFS、SMB、SysV、PROC等。在Linux系统中,每个

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

分区都是一个文件系统,都有自己的目录层次结构,Linux可以将这些文件系统直接挂载为系统的

一个目录。Linux支持多种文件系统,这样使得它更加灵活,并可以和许多其他种操作系统共存。

Virtual File System(虚拟文件系统)使得Linux可以支持多个不同的文件系统。由于系统已将Linux

文件系统的所有细节进行了转换,所以Linux核心的其他部分及系统中运行的程序将看到统一的文

件系统。Linux的虚拟文件系统允许用户能同时透明地安装许多不同的文件系统。虚拟文件系统是

为Linux用户提供快速且高效的文件访问服务而设计的。随着Linux的不断发展,它所支持的文件

格式系统也会越来越多。

11. 开发功能强

Linux支持一系列的UNIX开发,Linux已经具有全部UNIX特征,它是一个完整的UNIX开发

.

c

o

o

b

n

平台,几乎所有的主流程序设计语言都已移植到Linux上并可免费得到许多有用的源代码和库,如

C、C++、Fortran77、ADA

、PASCAL、Modual2和3、Tcl/TkScheme、SmallTalk/X等。

12. 具有强大的网络功能

Linux能很好的支持Internet,免费提供了大量支持Internet的软件。Internet本身是在UNIX领

域中建立并繁荣起来的,由于Linux与UNIX的特殊关系,在Internet这方面使用Linux是相当方便

t

e

n

k

.

w

w

w

b

n

c

.

的,用户能用Linux与世界上的其他人通过Internet网络进行通信。Linux支持文件传输。用户能通

过一些Linux命令完成内部信息或文件的传输。Linux支持远程访问。Linux不仅允许进行文件和程

序的传输,它还为系统管理员和技术人员提供了访问其他系统的窗口。通过这种远程访问的功能,

一位技术人员能够有效地为多个系统服务,即使那些系统位于相距很远的地方。实际上,Linux就

是依靠互联网才迅速发展了起来,Linux具有强大的网络功能也是自然而然的事情。它可以轻松地

c

.

w

w

w

与TCP/IP、LAN Manager、Windows for Workgroups、Novell Netware或Windows NT网络集成在一

打印服务器、邮件服务器、新闻服务器等等。

13. 设备独立性

起。Linux不仅能够作为网络工作站使用,更可以胜任各类服务器,如X应用服务器、文件服务器、

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

设备独立性是指操作系统把所有外部设备统一当作成文件来看待,只要安装它们的驱动程序,

任何用户都可以像使用文件一样,操纵、使用这些设备,而不必知道它们的具体存在形式。具有设

是具有设备独立性的操作系统,它的内核具有高度适应能力,随着更多的程序员加入Linux编程,

会有更多硬件设备加入到各种Linux内核和发行版本中。

14. 虚拟内存

备独立性的操作系统,通过把每一个外围设备看作一个独立文件来简化增加新设备的工作。Linux

虚拟内存技术,即拿出一部分硬盘空间来充当内存使用,当内存占用完时,电脑就会自动调用

硬盘来充当内存,以缓解内存的紧张。虚拟内存用硬盘空间充当内存来弥补计算机内存空间的缺乏。

当实际内存满时(实际上,在内存满之前),虚拟内存就在硬盘上创建了。当物理内存用完后,虚拟

内存管理器选择最近没有用过的,低优先级的内存部分写到交换文件上。这个过程对应用是隐藏的,

应用把虚拟内存和实际内存看作是一样的,这样就提高了系统的效率。

15. 动态链接共享库

每个应用程序共享一个公用的、运行时可调用的子程序库,而不是保留各自的软件备份,这样可

以为系统节省大量空间。在/lib目录下,就有许多以.so

作后缀的文件,这就是Linux系统应用的动态

链接库,以so结尾,即Shared Object,共享对象。(在Linux下,静态函数库是以.a作后缀的)X-Window

作为Linux下的标准图形窗口界面,它本身就采用了很多的动态链接库(在/usr/X11R6/lib目录下),

以方便程序间的共享,节省占用空间。著名的Apache网页服务器,也采用了动态链接库,以便扩充

※ 3 ※

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

程序功能。这就是动态链接的好处。

2 Linux下C语言简介

o

t

e

n

k

.

Linux作为一个优秀的操作系统,一项非常重要的功能就是支持系统调用尤其是支持C语言的

系统调用功能十分的方便、快捷。C语言具有高速、灵活、简洁、可移植性好等特点,从而很快成

为了世界上最受欢迎的编程语言之一。它和Linux是完美的结合,Linux为C语言提供了很好的支

持,为用户提供一个强大的编程环境。事实上,Linux和C语言天生有不解之缘,Linux操作系统是

用C语言写的,Linux下的很多软件也是用C语言写的,特别是一些著名的服务软件,比如MySQL、

Apache、Oracle等。

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

3 C语言简介及其特点

.

c

o

o

b

n

1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言。

1967年,剑桥大学的Matin Richards 对CPL语言进行了简化,于是产生了BCPL语言。1970年,

AT&T贝尔实验室的Ken Thompson将BCPL进行了修改并设计出更加先进的BCPL并取名为“B语

言”。并且他用B语言写了第一个UNIX操作系统。1973年,AT&T贝尔实验室的e在B

语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就

是C语言。

随着C语言在各种计算机上的快速推广,从而出现了许多C语言版本。这些版本虽然是类似的,

但并不兼容。为了明确定义与机器无关的C语言,1989年美国国家标准协会制定了C语言的标准

(ANSI C)。在ANSI标准化后,C语言的标准在相当长的一段时间内都基本保持不变,Normative

Amendment1在1995年开发了一个新的C语言版本,但是这个版本很少为人所知。ANSI标准在20

世纪90年代又经历了一次比较大的改进,这就是ISO9899:1999(1999年出版)。这个版本就是现在

所说的C99,成为现行的C语言标准。

t

e

n

k

.

w

w

w

b

n

c

.

C语言之所以发展迅速,而且成为最受欢迎的语言之一,主要是因为它具有强大的功能。许多

著名的系统软件,如UNIX/Linux、Windows

、DBASE Ⅲ PLUS、DBASE Ⅳ都是用C语言编写的。

c

.

w

w

w

用C语言加上一些汇编语言子程序,就更能显示C语言的优势,像PC-DOS、WORDSTAR等就是

用这种方法编写的。

总而言之,C语言具有以下特点:

1. C语言是中级语言

C语言被程序员广泛使用的一个重要原因是可以用它代替汇编语言。汇编语言使用的汇编指令,

是能够在计算机上直接执行的二进制机器码的符号表示。汇编语言的每个操作都对应为计算机执行

的单一指令。虽然汇编语言给予程序员达到最大灵活性和最高效率的潜力,但开发和调试汇编语言

程序的困难是难以忍受的。非结构性使得汇编语言程序难于阅读、改进和维护。也许更重要的是,

汇编语言程序不能在使用不同CPU的机器间移植。C语言同时具有汇编语言和高级语言的优势,它

把高级语言的基本结构和语句与低级语言的实用性结合起来。C语言可以像汇编语言一样对位、字

节和地址进行操作,而这三者是计算机最基本的工作单元。

2. C语言是结构式语言

结构化语言比非结构化语言更易于程序设计,用结构化语言编写的程序的清晰性使得它们更易

于维护。这已是人们普遍接受的观点了。结构式语言的显著特点是代码及数据的模块化,即程序的

各个部分除了必要的信息交流外彼此独立。这种结构化方式可使程序层次清晰,便于使用、维护以

及调试。语言是以函数形式提供给用户的,这些函数可方便地调用,并采用多种循环、条件语句控

制程序流向,从而使程序完全结构化。在C语言中,除实现顺序、选择和循环三种基本结构等的9

不仅要学习这9条控制语句和各种运算符,而且要学习并掌握常用标准库函数的使用。

3. C语言简洁、灵活,运算符和数据结构类型极其丰富

所有的高级语言都支持数据类型的概念。一个数据类型定义了一个变量的取值范围和可在其上

※ 4 ※

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

条控制语句外,输入输出操作均由标准库函数(不是C语言的组成部分)来实现。所以学习C语言,

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

操作的一组运算。常见的数据类型是整型、字符型和实数型。虽然C语言有五种基本数据类型,但

与Pascal或Ada相比,它却不是强类型语言。C程序允许几乎所有的类型转换。例如,字符型和整

型数据能够自由地混合在大多数表达式中进行运算。这在强类型高级语言中是不允许的。C语言的

另一个重要特点是它仅有32个关键字,这些关键字就是构成C语言的命令。和IBM PC的BASIC

相比,后者包含的关键字达159个之多。

4. C语言可移植性好

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

C语言程序非常容易移植,可移植性表示为某种计算机写的软件可以用到另一种机器上去。举

例来说,如果为苹果机写的一个程序能够方便地改为可以在IBM PC上运行的程序,则称为是可移

植的。几乎所有的计算机上都有C语言编译程序,因此可以很少改动甚至不加改动地将为一种机器

写的C语言源程序在另一种机器上编译执行。可移植性节省了时间和财力。

5. C语言生成的目标代码质量高,程序执行效率高

C语言具有各种各样的数据类型,并引入了指针概念,可以直接操纵硬件。可使程序执行效率

更高,但这也使得初学者难于掌握它。用C语言编程,可以获得高效机器代码,其效率几乎接近汇

编语言代码。

6. C语言适用范围大

n

c

.

o

o

b

C语言最初被用于系统程序设计。一个系统程序是一大类程序的一部分,这一大类程序构成了

t

e

n

k

.

w

w

w

b

n

c

.

计算机操作系统及实用程序。通常被称为系统程序的有:操作系统翻译程序、编辑程序、汇编程序、

编译程序、数据库管理程序。随着C语言的普及,加之其可移植性和高效率,许多程序员用它设计

各类程序。而且计算功能、逻辑判断功能也强大,可以实现决策目的。C语言也有强大的图形处理

功能,支持多种显示器和驱动器。

4 Linux程序设计基础知识

4.1 头文件

glibc_header是Linux下的系统头文件。缺少了系统头文件的话,很多用到系统功能的C程序

c

.

w

w

w

将无法编译。假如用户在安装过程中少装了这些包,就会无法编译C源程序。在使用C语言和其他

语言进行程序设计的时候,需要头文件来提供对常数的定义和对系统及库函数调用的声明。对C语

言来说,这些头文件几乎永远保存在/usr/include及其下级子目录里。那些依赖于所运行的UNIX或

他的程序设计软件也可以有一些预先定义好的声明文件,它们的保存位置可以被相应的编译器自动

查找到。比如,X窗口系统的/usr/include/X1R6子目录和GNU C++编译器的/usr/include/g++ -2子目

录等。

在调用C语言编译器的时候,可以通过给出“ -I”编译命令标志来引用保存在下级子目录或者

非标准位置的头文件。用grep命令来查找含有某些特定定义与函数声明的头文件是很方便的。

头文件的保存位置:

(1)/usr/include:系统头文件。

(2)/usr/local/include:本地头文件。

Linux操作系统特定版本的头文件一般可以在/usr/include/sys或/usr/include/linux子目录里找到。其

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

4.2 函数库

函数库是一些预先编译好的函数的集合,那些函数都是按照可再使用的原则编写的。它们通常

由一组互相关联的用来完成某项常见工作的函数构成。比如用来处理屏幕显示情况的函数(curses

库)等。

标准的系统库文件一般保存在/lib或者/usr/lib子目录里。编译时要告诉C语言编译器(更确切

须遵守一定的命名规则,还必须在命令行上明确地给出来。

库文件的名字永远以lib这几个字母打头,随后是说明函数库情况的部分(比如用c表示这是

※ 5 ※

地说是链接程序)应去查找哪些库文件。默认情况下,它只会查找C语言的标准库文件。库文件必

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

一个C语言库;而m表示这是一个数学运算库等)。文件名的最后部分以一个句点(.)开始,然后

给出这个库文件的类型,如下所示:

(1).a传统的静态型函数库。

(2).so和.sa共享型函数库(见下面的解释)。

函数库一般分为静态和共享两种格式,用ls /usr/lib命令查一下就能看到。在通知编译器查找某

个库文件的时候,既可以给出其完整的路径名,也可以使用-l标志。

1. 静态库

函数库最简单的形式就是一组处于可以“拿来就用”状态下的二进制目标代码文件。当有程序

需要用到函数库中的某个函数时,就会通过include语句引用对此函数做出声明的头文件。编译器和

链接程序负责把程序代码和库函数结合在一起成为一个独立的可执行程序。如果使用的不是标准的

C语言运行库而是某个扩展库,就必须用-l选项指定它。

静态库也叫做档案(archive),它们的文件名按惯例都以.a结尾。比如C语言标准库为

/usr/lib/libc.a、X11库为/usr/X11R6/lib/libX11.a等。

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

.

c

o

o

b

n

c

.

w

w

w

自己建立和维护静态库的工作也并不困难,用ar(“建立档案”的意思)程序就可以做到,另

外要注意的是,应该用gcc -c命令对函数分别进行编译。应该尽量把函数分别保存到不同的源代码

文件里去。如果函数需要存取普通数据,可以把它们放到同一个源代码文件里并使用在其中声明为

static类型的变量。

GNU的C函数库,即glibc,是Linux上最重要的函数库,它定义了ISO C标准指定的所有的

库函数,以及由POSIX或其他UNIX操作系统变种指定的附加特色,还包括有与GNU系统相关的

扩展。glibc基于如下标准:

(1)ISO C: C编程语言的国际标准,即ANSI C

(2)POSIX:GNU C 函数库实现了ISO/IEC 9945-1:1996(POSIX系统应用程序编程接口,即

POSIX.1)指定的所有函数。该标准是对ISO C的扩展,包括文件系统接口原语、设备相关的终端

控制函数以及进程控制函数。同时,GUN C函数库还支持部分由ISO/IEC 9945-2:1993(POSIX Shell

和工具标准,即POSIX.2)指定的函数,其中包括用于处理正则表达式和模式匹配的函数。

(3)Berkeley UNIX:BSD和SunOS。GNU C函数库定义了某些UNIX版本中尚未标准化的函

数,尤其是4.2BSD、4.3 BSD、4.4BSD UNIX系统(即“Berkeley Unix”)以及“SunOS”(流行的

4.2BSD变种,其中包含有某些Unix System V的功能)。BSD函数包括符号链接、select函数、BSD

信号处理函数以及套接字等等。

(4)SVID:System V的接口描述。GNU C函数库定义了大多数由SVID指定而未被ISO C和

POSIX标准指定的函数。来自System V的支持函数包括进程间通信和共享内存、hsearch和drand48

函数族、fmtmsg以及一些数学函数。

(5)XPG:X/Open可移植性指南。GNU C函数库遵循X/Open可移植性指南(Issue 4.2

)以及

所有的XSI(X/Open系统接口)兼容系统的扩展,同时也遵循所有的X/Open UNIX扩展。

除glibc之外,流行的Linux发行版中还包含有一些其他的函数库,这些函数库具有重要地位,

例如:

t

e

n

k

.

w

w

w

b

n

c

.

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

(1)GNU Libtool:GNU Libtool实际是一个脚本生成工具,它可以为软件包开发者提供一般性

的共享库支持。以前,如果源代码包的开发者要利用共享库的优点,则必须为每个软件包可支持的

平台编写定制的支持代码。并且还需要设计配置接口,以便软件包的安装程序能够正确选择要建立

的库类型。利用GNU Libtool,则可以简化开发者的这一工作。它在一个单独的脚本中同时封装了

与平台相关的依赖性以及用户界面。GNU Libtool可使每个宿主类型的完整功能可通过一般性的接

口获得,同时为程序员隐藏了宿主的特殊性。GNU Libtool一致性接口是可靠的,用户不必阅读那

些晦涩的文档,以便在每个平台上建立共享库。他们只需运行软件包的配置脚本,而由libtool完成

繁复的工作。

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

(2)CrackLib:CrackLib为用户提供了一个C语言函数接口,利用这一函数,可避免用户选择

容易破解的密码。该函数库可在类似passwd的程序中使用。

※ 6 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

(3)LibGTop:LibGTop是一个能够获取进程信息以及系统运行信息的函数库,这些信息包括:

系统的一般信息、SYS V IPC限制、进程列表、进程信息、进程映射、文件系统使用信息等。

(4)图形文件操作函数库:包括libungif、libtiff、libpng、Imlib、libjpeg等,可分别用来操作

o

t

e

n

k

.

GIF、TIFF、PNG、JPEG以及其他一些格式的图形文件。

2. 共享库

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

静态库的缺点是,如果在同一时间运行多个程序而它们又都使用着来自同一个函数库里的函数

时,内存里就会有许多份同一函数的备份,在程序文件本身也有许多份同样的备份。这会消耗大量

宝贵的内存和硬盘空间。

许多UNIX系统支持共享库,它同时克服了在这两方面的无谓消耗。对共享库和它们在不同系统

.

c

o

o

b

n

上实现方法的详细讨论超出了本书的范围,本书把注意力集中在眼前 Linux环境下的实现方法上。

共享库的存放位置和静态库是一样的,但有着不同的文件后缀。在一个典型的Linux系统上,

C语言标准库的共享版本是/usr/lib/ N,其中的N是主版本号。

3. 共享库及其相关配置

(1)/etc/:包含共享库的搜索位置。

(2)ldconfig:共享库管理工具,一般在更新了共享库之后要运行该命令。

(3)ldd:可查看可执行文件所使用的共享库。

4. 函数库的保存位置

(1)/lib:系统必备共享库。

(2)/usr/lib:标准共享库和静态库。

(3)/usr/i486-linux-libc5/lib:

libc5兼容性函数库。

(4)/usr/X11R6/lib:X11R6的函数库。

(5)/usr/local/lib:本地函数库。

t

e

n

k

.

w

w

w

b

n

c

.

4.3 系统调用

c

.

w

w

w

系统调用是操作系统提供给外部程序的接口。在C语言中,操作系统的系统调用通常通过函数

调用的形式完成,这是因为这些函数封装了系统调用的细节,将系统调用的入口、参数以及返回值

用C语言的函数调用过程实现。在Linux系统中,系统调用函数定义在glibc中。

谈到系统调用时,需要注意如下几点:

(1)系统调用函数通常在成功时返回0值,不成功时返回非0值。如果要检查失败原因,则要

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

判断errno这个全局变量的值,errno中包含有错误代码。

(2)许多系统调用的返回数据通常通过引用参数传递。这时,需要在函数参数中传递一个缓冲

区地址,而返回的数据就保存在该缓冲区中。

(3)不能认为系统调用函数就要比其他函数的执行效率高。要注意,系统调用是一个非常耗时

的过程。

4.4 帮助文档

1. man

man,即manunal,是UNIX系统手册的电子版本。根据习惯,UNIX系统手册通常分为不同的

部分(或小节,即section),每个小节阐述不同的系统内容。目前的小节划分如下:

(1)命令:普通用户命令。

(2)系统调用:内核接口。

(3)函数库调用:普通函数库中的函数。

(4)特殊文件:/dev目录中的特殊文件。

(5)文件格式和约定:/etc/passwd等文件的格式。

(6)游戏。

(7)杂项和约定:标准文件系统布局、手册页结构等杂项内容。

※ 7 ※

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

(8)系统管理命令。

(9)内核例程:非标准的手册小节。便于Linux内核的开发而包含。

(10)其他手册小节:

① l: PostgreSQL数据库命令。

② n: TCL/TK命令。

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

.

n

手册页一般保存在/usr/man目录下,其中每个子目录(如 man1, man2, ..., manl, mann)包含不

n

c

.

o

o

b

同的手册小节。使用man命令查看手册页。

man命令行:

man [-acdfFhkKtwW] [-m system] [-p string] [-C config_file] [-M path] [-P pager] [-S section_list]

[section] name

常用命令行:

$ man open

$ man 7 man

$ man ./myman.3

2. info

Linux中的大多数软件开发工具都是来自自由软件基金会的GNU项目,这些工具软件的在线文

t

e

n

k

.

w

w

w

b

n

c

.

档都以info文件的形式存在。info程序是GNU的超文本帮助系统。

info文档一般保存在/usr/info目录下,使用info命令查看info文档。要运行info,可以在shell

c

.

w

w

w

提示符后输入info,也可以在GNU的emacs中键入ESC-x后跟info。

info帮助系统的初始屏幕显示了一个主题目录,可以将光标移动到带有*的主题菜单上面,然后

按回车键进入该主题,也可以键入m,后跟主题菜单的名称而进入该主题。例如,可以键入m,然

后再键入gcc而进入gcc主题中。

如果要在主题之间跳转,则必须记住如下的几个命令键:

* n:跳转到该节点的下一个节点。

* p:跳转到该节点的上一个节点。

* m:指定菜单名而选择另外一个节点。

* f:进入交叉引用主题。

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

* l:进入该窗口中的最后一个节点。

* TAB:跳转到该窗口的下一个超文本链接。

* RET:进入光标处的超文本链接。

* u:转到上一级主题。

* d:回到info的初始节点目录。

* h:调出info教程。

* q:退出info。

3. HOWTO

可供用户参考的联机文档的另一种形式是HOWTO文件,这些文件位于系统的/usr/doc/HOWTO

目录下。HOWTO文件的文件名都有一个-HOWTO后缀,并且都是文本文件。每一个HOWTO文件

包含Linux某一方面的信息,例如它支持的硬件或如何建立一个引导盘。要想查看这些文件,进入

/usr/doc/HOWTO目录,使用more命令,具体形式如下:

$ cd /usr/doc/HOWTO

$ more topic-name-HOWTO

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

另外,HOWTO文档还有其他格式的文件,例如HTML和PS等,保存在/usr/doc/HOWTO

/other-formats下。

4. 其他

Linux的内核文档一般包含在内核源代码中,目录如下:/usr//Documentation

/usr/doc。目录下包含有大量与特定软件或函数库相关的说明性文档。

※ 8 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

5 Linux下C语言编程环境

5.1 vi编辑器的使用

o

t

e

n

k

.

.

c

o

o

b

n

1. vi简介

vi(Very involved),意思是包含全部。对UNIX操作系统而言,大多数UNIX系统都具有各自

类型的编辑器,但是实际使用的工具不尽相同,这取决于使用的UNIX系统。但是,几乎所有Linux

操作系统机器上都安装有vi可视化编辑器。一旦掌握vi的使用技巧,就可以在所有的Linux操作系

统中随意编辑文件。

vi是一个功能非常强大的编辑器,可以满足任何操作。vi可以在操作的时候让读者编辑和浏览

整个文件。以前的许多编辑器,比如ed都是行编辑器,即每次只能编辑和浏览一行文字。因此相比

于过去的UNIX编辑器,vi更加便于整个文件的浏览。

在机器上安装vi无需特别的安装路径,对此无需太多担心。当安装系统的时候,vi自动会出现。

因为系统管理员需要使用vi处理很多工作,包括创建系统文本等。RedHat的Linux在系统中提供了

安装特定编辑器的选择,但是在Linux操作系统不安装vi的情况相当少见。

2. 进入vi

在系统提示字符(如$、#)下敲入vi <文件名称>,vi可以自动载入所要编辑的文件或是开

启一个新文件(如果该文件不存在或缺少文件名)。进入vi后屏幕左方会出现波浪符号,凡是行首

有该符号就代表此行目前是空的。

现在读者可以动手试用一下。首先,在的工作站打开一个终端窗口,只需在$提示中输入vi然

后按回车键就可以启动vi编辑器。

接着,将看到弹出一个页面左下角有一个“~”符号的空白文件。当对文件保存之后,这个符

号就不会显示出来。

若要编辑某个文件或者为一空白文件命名,可输入vi filename。vi filename可以是一个已经存

在的文件名或者是一个给新文件指定的名称。

3. 三种模式

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

n

k

.

w

w

w

b

n

c

.

c

.

w

w

w

在介绍如何使用vi之前,了解vi具有三种基本模式是很重要的。这三种基本模式为输入模式、

命令模式和底行模式。在命令模式下输入的按键将做为命令来处理:如输入a,vi即认为是在当前

位置插入字符。而在输入模式下,vi则把输入的按键当作插入的字符来处理。命令模式切换到输入

模式只需键入相应的输入命令即可(如a,A),而要从输入模式切换到命令模式,则需在输入模式

下按[ESC],如果不知道现在是处在什么模式下,可以多按几次[ESC],系统如发出嘟嘟声就表示已

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

处于命令模式下了。在底行模式下可以将文件保存或退出vi,也可以设置编辑环境,如寻找字符串、

列出行号等。在命令模式下按[:]键可以切换到底行模式。一般在使用时把vi简化成两个模式,就是

将底行模式也算入命令行模式。

在默认状态下,vi在命令模式下启动,因此输入命令时不会显示文字,除非输入命令切换至输

入模式。大多数vi命令不会在屏幕上显示任何东西,读者只需要知道它们的工作过程就足够了。

以下命令可以从命令模式进入输入模式:

(1)插入(insert)。

i:这是一个输入命令,即从光标所在位置前面开始插入文字,光标后的文字随新增文字向后移

动。如果是一个空白文档,文字将会输入在文档的左上角。

I:在行开始处进入输入模式,即在当前行的开始处输入文字。与Word中的按Home键后输入

文字类似。

(2)新增(append)。

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

a:这是一个新增命令,即从光标所在位置后面开始新增文字,光标后的资料随新增文字向后移

动。

A:这是一个新增到行命令的操作,即从光标所在行最后面的地方开始新增文字。这与Word

中的按下[End]键后输入文字类似。

※ 9 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

(3)开始(open)。

o:这是一个命令之下的打开行命令,即在光标所在行下面新增一行并进入输入模式。

O:这是一个命令之上的打开命令,即在光标所在行上方新增一行并进入输入模式。

4. 退出vi

.

c

o

o

b

n

c

.

w

w

w

在命令模式下键入:q,:q!,:wq或:x(注意:号),就会退出vi。其中:wq和:x是存盘退出,而:q

是直接退出,如果文件已有新的变化,vi会提示保存文件而:q命令也会失效,这时可以用:w命令保

存文件后再用:q退出,或用:wq或:x命令退出,如果不想保存改变后的文件,就需要用: q!命令,这

个命令将不保存文件而直接退出vi。

5. 基本编辑

配合一般键盘上的功能键,如方向键、[Insert]、[Delete]等等。当然vi还提供其他许许多多功

能让文字的处理更为方便。

删除与修改文件的命令:

x:删除光标所在字符。

dd:删除光标所在的行。

r:修改光标所在字符,r后直接输入要修正的字符。

R:进入取替换状态,新增文字会覆盖原先文字,直到按[ESC]回到命令模式下为止。

s:删除光标所在字符,并进入输入模式。

S:删除光标所在的行,并进入输入模式。

dw:删除文字命令,即删除光标处的文字。

D:删除到行末端,即删除从光标所在位置到行末端的所有文本。

cw:改变文字命令,即光标所有位置的文字将随着输入文字而改变,直到按下[Esc]键。

绝大多数指令都可以通过组合而提高其功能。例如,如果输入2dd,vi将删除两行文本。

剪切与粘贴等操作:

与其他很多编辑器一样,读者可以在文档中使用剪切与粘贴文本。以下命令是可以使用的最为

简单的剪切与粘贴操作。

yy:复制行命令。光标所在行的整行文本将被复制到类似剪切板的缓冲器。

yw:复制字符命令。光标所在行从光标处直到行尾的字符将被复制到类似剪切板的缓冲器。

p:后放置命令。在当前光标位置之后放置或粘贴缓冲器的内容。对于复制行命令,缓冲器的内

容将被粘贴在当前行之后。对于复制字符行命令,缓冲器内容将被粘贴在光标的右边。

P:前放置命令。在当前光标位置之前放置或粘贴缓冲器的内容。对于复制行命令,缓冲器的

内容将被粘贴在当前行之前。对于复制字符行命令,缓冲器内容将被粘贴在光标的左边。

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

n

k

.

w

w

w

b

n

c

.

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

使用复制和放置命令时,也可以利用字符加复制命令的方式使用多个缓冲器或剪切板。这些字

符可为a-z,并且只能是小写字母。例如,ayy将当前行内容复制到缓冲器a,ap命令将缓冲器a中

的内容粘贴在当前行之前。

vi中undo命令也很重要,并且十分简单:只需要在命令模式下按下u键就可以撤消最近使用

的一次指令。

与undo命令类似的是redo命令。按下句号键(.)将会重新键入最近的命令。例如,如果使用

cw来改变几个文字,在改变第一个文字后,可以查找下一文字然后使用句号(.)就可以改这一文

字了。

查找与替代命令:

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

/ 所查字符:向后查找字符。先按/键,再输入想寻找的字符,如果第一次找的关键字不是您想

要的,可以一直按n会往后寻找到您要的关键字为止。这时按大写N则相反的向前查找。

? 所查字符:向前查找字符。先按?键,再输入您想寻找的字符,如果第一次找的关键字不是您

想要的,可以一直按n会往前寻找到您要的关键字为止。这时按大写N则相反的向后查找。/、?前

者是向后查找,后者为向前查找。

:s/find_text/replace_text/:对查找命令稍加改变,它将具有查找后替换的功能。上面这条命令的

※ 10 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

功能就是遍寻整个文件,查找到第一个含有find_text字符串的行,然后将这行中的find_text替换成

replace_text。其中“s”表示替换。如果想将文件中所有find_text替换成replace_text,可以在前面加

上一个“%”(所有行),后面加上一个“g”(全局),比如:%s/find_text/replace_text/g。

o

t

e

n

k

.

.

c

o

o

b

n

:3,7s/old_string/new_string/:仅将文件中第3行到第7行中的“old_string”替换成“new_string”。

:1,$s/^M//g:将DOS格式文本转成UNIX格式文本的时候会出现^M的字符串,它们表示DOS

下的回车。要去掉它们可用上面这行命令。其中^M是同时按Ctrt+^+M出来的。

:g/^/s//NewString/g

:%s/^/NewString/g

在文本每行的行首添加字符串“NewString”。这里“^”表示行首。

:g/$/s//NewString/g

:%s/$/NewString/g

在每行的行尾添加字符串“NewString”。这里“$”表示行尾。

:3,$s/^/NewString/:从文本的第3行至最后一行的行首全部插入字符串“NewString”。

注意:其中“s”为表示替换动作,“%”表示所有行,“g”表示全文,“^”表示行首或段首,“$”

表示行尾或段尾。

重要的是一定注意,只有输入内容完全匹配,Vi才可以查找到。vi不支持混合查找或者模糊查

找。

光标移动命令:

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

n

k

.

w

w

w

b

n

c

.

c

.

w

w

w

输入跟编辑都是可以在输入模式下完成的。例如要删除字符,直接按[Delete]就可以了。而插入

状态与取代状态可以直接用[Insert]切换,用不着用命令模式的编辑指令。这些指令几乎是每台终端

机都能用,而不是仅仅在PC上。在命令模式下移动光标的基本指令是h,j,k,l。

当然也可以直接用PC的方向键来移动光标。

接下来需要学习vi中的浏览命令。以命令模式在文档中移动,可以使用以下的命令:

h:将一个文字移动到左边。

j:往下移动一个文字。

k:往上移动一个文字。

l:将一个文字移动到右边。

[Ctrl]f:向前移动一页指令。这将使得光标在文本中向前移动一页。

[Ctrl]b:向后移动一页指令。这将使得光标在文本中向后移动一页。

[Ctrl]u:向下移动半页指令。这将使得光标在文本中向下移动半页。

[Ctrl]d:向上移动半页指令。这将使得光标在文本中向上移动半页。

^:光标将会移动到行的开始处。

$:光标将会移动到行的结束处。

w:移动到上一个文字的开始。

b:移动到下一个文字的开始。

e:移动到一个文字的末端。

G:移动到文件的末端。

数字0:移到文章的开头。

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

数字n:跳至指定的行。

[Ctrl]g:列出光标所在行的行号。

#G:例如,5G表示移动光标至文章的第5行行首。

#:#号表示一个数字,在命令模式输入:号进入底行模式后输入一个数字,再按回车键就会跳

到该行了,如输入数字15,再按回车键,就会跳到文章的第15行。

加密和解密文件命令:

文件就已经被加密了。

在命令模式输入“:X”命令,接着输入密码、确认输入密码,最后输入“:wq”命令保存退出。

※ 11 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

经过上面方法加密后的文件变成加密文件。要阅读原来的明文,则在打开文件后,会提示用户

输入密码。如果密码输入正确,就能看到原来的明文。另外可以看到,在最后的状态行上有此文件

已被加密的提示。

取消加密的方法很简单。在命令模式输入“:X”命令,首先会提示输入密码,这时直接按回车

键。接下来在提示重复输入密码时也直接按回车键,最后输入“:wq”命令保存退出。这样文件的加

密就被取消了。

6. 助力编程

(1)语法加亮。

在vi中编写程序,如果为了编程的方便而想开启语法加亮功能,只需在命令模式下输入“:syntax

on”即可。同理可知,如果想关闭语法加亮功能,就在命令模式下输入“:syntax off”。

(2)快速查看函数帮助。

在用vi阅读和编写程序(主要是指C或C++程序)时,如果需要了解某个函数的具体功能,可

以将光标移到该函数上,然后在命令模式下输入“K”,就可以调动“Linux Programmer's Manual”

中对此函数的man帮助。

(3)“ctags”命令。

在阅读和编写C或C++程序时,可用“ctags”命令对当前目录下的C源程序进行扫描。命令如

下:

$ ctags *.c

上面一条命令将为当前目录下的.c文件生成tags文件,然后可以使用“ta函数名”命令来快速

打开相应函数所在文件,并将光标定位在对应函数的开头。

(4)自动对齐。

在命令模式下使用“:set ai”命令可以让程序中各行自动对齐。

(5)显示匹配。

在编程中{}、[]、()

常常是成对出现的,而且常常有多层的嵌套,很容易遗漏和失误。所以下面

的这个技巧非常有用。在命令模式下使用“:set sm”命令会在用户输入)、]、}时显示出对应匹配的

{、[、(来。

(6)缩写文本。

o

t

e

n

k

.

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

.

c

o

o

b

n

t

e

n

k

.

w

w

w

b

n

c

.

c

.

w

w

w

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

在编程中常常要输入一些重复且很长的信息,比如较长的名词和公司信息等,这时可以用vi

的缩写功能。它可以将一个很长的词用一个很短的缩写来代替。比如一个较长的URL,可以给它一

个缩写,在命令模式下使用“:ab myurl ”,然后在插入模式下输入“myurl”

后,“myurl”就会自动变成刚才定义的那个长的URL。另外,在插入模式下输入“:una myurl”,则

是取消“myurl”这个缩写。

(7)set选项。

使用“:set”可以设置vi的环境变量。vi的环境变量有很多。使用“:set all”可以显示所有环境

变量。使用“:set变量名及参数”可以设置对应的环境变量。

下面的命令可显示行号:

:set nu

下面的命令可将文件设为只读:

:set readonly

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

下面的命令使vi在“:q”和“:!”命令之前都自动保存文件:

:set autowrite

下面的命令显示用户处在什么模式下:

:set showmode

同理,“:set noshowmode”就是关闭此显示。

助查到对应的环境变量的详细作用。

※ 12 ※

vi环境变量还有很多。了解它们,将给用户使用vi带来更多方便。用户可以通过vi的联机帮

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

.

c

o

o

b

n

c

.

w

w

w

(8)使用宏。

vi的宏提供了更强大的功能,用户可以根据自己的需要来定制自己的宏,然后通过宏来完成事

先定义好的一整套操作。用“map”来定义一个宏,用“unmap”来删除。在熟悉了vi的基本命令

后,将这些命令组合起来就能完成复杂的工作。如果再将这些命令的组合定义成宏的话,就可以方

便用户经常性地调用了。这是一个非常强大的功能。

7. Vi常用的指令总结

(1)新增(append)。

a:从光标所在位置后面开始新增资料,光标后的资料随新增资料向后移动。

A:从光标所在行最后面的地方开始新增资料。

(2)向后(back)。

b:光标左移一个字至字首(以所有可能的字符为分隔符)。

B:光标左移一个字至字首(以回车和空格为分隔符)。

(3)修改(change)。

c:删除文字,并且进入插入模式。要与其他命令一起使用。

如:cl,ch,cj,ck,cw,cb,cW,cB,c0,c$,c(,c),c{,c}。

C:删除光标到该行结束为止所有的文字,并且进入插入模式。

(4)删除(delete)。

d:删除文字后,还是在编辑模式。要与其他命令一起使用,

如:dl,dh,dj,dk,dw,db,dW,dB,d0,d$,d(,d),d{,d}。

D:删除光标到该行结束为止所有的文字。

(5)移动(move)。

e:光标右移一个字至字尾(以所有可能的字符为分隔符)。

E:光标右移一个字至字尾(以回车和空格为分隔符)。

fx:往右移动到x字符上。

Fx:往左移动到x字符上。

gg:移动到文件的第一行的第一个字符。

G:移动到文件的最后一行的第一个字符。

h:光标左移一个字符。

H:移动到屏幕的第一行的行首。

(6)插入(insert)。

i:从光标所在位置前面开始插入资料,光标后的资料随新增资料向后移动。

I:从光标所在行的第一个非空白字符前面开始插入资料。

j:光标下移一行。

J:删除光标所在行的下面那一行。

k:光标上移一行。

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

n

k

.

w

w

w

b

n

c

.

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

K:快速查看函数帮助。在用vi阅读和编写程序(主要是指C或

C++程序)时,如果需要了解

某个函数的具体功能,可以将光标移到该函数上,然后在命令模式下输入“K”,就可以调动“Linux

Programmer's Manual”中对此函数的man帮助。

l:光标右移一个字符。

L:光标移动到屏幕的最后一行。

(7)下一个(next)。

M:光标移动到屏幕的中间那一行。

n:配合/或?使用,重复一次。

(8)开始(open)。

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

N:配合/或?使用,反方向重复一次。

o:在光标所在行下新增一行并进入输入模式。

※ 13 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

.

c

o

o

b

n

c

.

w

w

w

O:在光标所在行上方新增一行并进入输入模式。

(9)放置(put)。

p:后放置命令。在当前光标位置之后放置或粘贴缓冲器的内容。对于复制行命令,缓冲器的内

容将被粘贴在当前行之后。对于复制字符行命令,缓冲器内容将被粘贴在光标的右边。

P:前放置命令。在当前光标位置之前放置或粘贴缓冲器的内容。对于复制行命令,缓冲器的

内容将被粘贴在当前行之前。对于复制字符行命令,缓冲器内容将被粘贴在光标的左边。

(10)替换(replace)。

r:修改光标所在字符,r后接要修改的字符。

R:进入取替换状态,新增文字会覆盖原先文字,直到按[Esc]键回到命令模式下为止。

s:删除光标所在字符,并进入输入模式。

S:删除光标所在的行,并进入输入模式。

tx:往右移动到x字符前。

Tx:往左移动到x字符前。

(11)撤消(undo)。

u:撤消。

U:恢复光标所在行(如果光标所在行没有改变,则光标跳到最近的有改变过的行)的所有改

变。

(12)可视化的选择(visual)。

v:一个字符一个字符的选择。

V:一行一行的选择。

(13)字符(word)。

w:光标右移一个字至字首(以所有的可能的字符为分隔符)。

W:光标右移一个字至字首(以回车和空格为分隔符)。

x:删除光标后面的字符。

X

:删除光标前面的字符。

(14)复制(yank)。

y:复制命令。要与其他命令一起使用,如:yl,yh,yj,yk,yw,yb,yW,yB,y0,y$,y(,

y),y{,y}。

Y:复制一行命令。

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

n

k

.

w

w

w

b

n

c

.

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

vi是类Unix操作系统上常用的缺省编辑器。了解了vi,用户就能利用它高效地编辑文件。学

习vi的过程会很长,因为它的功能很多。不过它确实是一个值得花时间来学习的工具。所谓“工欲

善其事,必先利其器”,只要勤加练习和总结,一定能熟练掌握这一文本编辑的利器。

5.2 GCC编译器简介

Linux中最重要的软件开发工具是GCC(GNU C Compiler)。它是GNU的代表作品之一。GCC

是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效

率要高20%~30%。

GCC编译器能将C、C++语言源程序编译、链接成可执行文件,如果没有给出可执行文件的名

字,GCC将生成一个名为的文件。

GCC的基本用法:

gcc [options] [filenames]

options是指参数集,filenames 是指文件集

如果有两个或少数几个C源文件,也可以方便地利用GCC编译、链接并生成可执行文件。例如

有两个源文件main.c和fac.c

,现在要编译生成一个计算阶乘的程序。

-----------------------

fac.c

-----------------------

※ 14 ※

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

.

c

o

o

b

n

c

.

w

w

w

#include

#include

int fac (int n)

{

return n<=1?1:fac (n - 1) * n;

}

-----------------------

-----------------------

main.c

-----------------------

#include

#include

int fac (int n);

int main (int argc, char **argv)

{

if (argc < 2) {

printf ("Usage: %s nn", argv [0]);

return -1;

} else {

int n = atoi (argv[1]);

printf ("Factorial of %d is %d.n", n, fac (n));

}

return 0;

}

-----------------------

利用如下的命令可编译生成可执行文件,并执行程序:

$ gcc -o fac main.c fac.c

$ ./fac 5

Factorial of 5 is 120.

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

.

n

t

e

.

n

t

e

n

k

.

w

w

w

b

n

c

.

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

5.3 GNU make简介

在一个工程中源文件往往不计其数,按其类型、功能、模块分别放在若干个目录中,Makefile

定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,

甚至于进行更复杂的功能操作。因此Makefile的目的就是自动确定一个软件包的哪些部分需要重新

编译,并用特定的命令去编译它们,准确地使用Makefile可以大大减少编译程序所花费的时间。

当一个适当的Makefile存在时,每次改变某些源文件,用简单的make命令,将足以完成所有

必须的重新编译,make程序利用Makefile的数据和每个文件更新一次时的更改的时间来确定哪些

文件需要更新;对每一个需要更新的文件,make程序使用Makefile中定义的命令来更新它。如果

make程序没有使用-f选项指定一个,那么make程序将在当前目录下按顺序寻找下列

列在目录的文件列表的最前面。

5.4 GDB调试工具简介

文件:GNUMakefile,Makefile,makefile。推荐使用Makefile,因为他的第一个字母是大写,通常

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

n

c

w

.

k

o

o

b

一个功能强大的调试器不仅为程序员提供了跟踪程序执行的手段,而且还可以帮助程序员找到

※ 15 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

解决问题的方法。对于Linux程序员来讲,GDB(GNU Debugger)通过与GCC的配合使用,为基

于Linux的软件开发提供了一个完善的调试环境。

GDB是GNU开源组织发布的一个强大的UNIX下的命令行调试工具。大家知道命令行的强大

o

t

e

n

k

.

就是在于其可以形成执行序列形成脚本。UNIX下的软件全是命令行的,这给程序开发提供了极大

的便利,命令行软件的优势在于,它们可以非常容易地集成在一起,使用几个简单的已有工具的命

令,就可以做出一个非常强大的功能。或许,有人比较喜欢那种图形界面方式的,如VC等调试,

但如果是在UNIX平台下做软件,读者会发现GDB这个调试工具有着比VC的图形化调试器更强大

一般来说,GDB主要完成下面四个方面的功能:

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

的功能。

(1)启动程序,可以按照自定义要求随心所欲地运行程序。

(2)可让被调试的程序在所指定的调置的断点处停住。(断点可以是条件表达式。)

.

c

o

o

b

n

(3)当程序被停住时,可以检查此时程序中所发生的事。

(4)动态地改变程序的执行环境。

从上面看来,GDB和一般的调试工具没有什么两样,基本上也是完成这些功能,不过在细节上,

读者可以看到GDB这个调试工具的强大,当然读者可能比较习惯了图形化的调试工具,但有时候,

命令行的调试工具却有着图形化工具所不能完成的功能。

t

e

n

k

.

w

w

w

b

n

c

.

6 Linux程序设计的特点

1. 集成性

Linux下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲

的功能。而Windows下的图形软件基本上是各自为营,互相不能调用,不利于各种软件的相互集成。

2. 简单性

许多有用的Linux软件开发工具的安装,使用都非常简单,使得开发程序变得容易。

3. 重点性

c

.

w

w

w

一个所谓功能齐全的程序可能既不容易使用,也不容易维护。如果程序只用于一个目的,那么

当更好的算法或更好的操作界面被开发出来的时候,它就更容易得到改进。在Linux世界里,通常

会在需求出现的时候把许多小的工具程序组合到一起来完成一项更大的任务,而不是用一个巨大的

程序预测一个用户的需求。

4. 可反复性

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

使用的程序组件把应用程序的核心部分组建成一个库。带有简单而又灵活的程序设计接口并且

文档齐备的函数库能够帮助其他人开发同类的项目,或者能够把这里的技巧用在新的应用领域。例

如dbm数据库函数库就是一套由不同功能的函数组成的集合,而不是一个单一的数据库管理系统。

5. 过滤性

许多Linux应用程序可以用作过滤器,即它们可以把自己的输入转换为另外一种形式的输出。

Linux提供的工具程序能够将其他Linux程序组合成相当复杂的应用软件,其组合方法既新颖又奇

特。当然,这类程序组合正是由Linux独特的开发方法支撑着的。

6. 开放性

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

文件格式比较成功和流行的Linux程序所使用的配置文件和数据文件都是普通的 ASCII文本。

在程序开发中遵循该原则是一种很好的做法。它使用户能够利用标准的软件工具对配置数据进行改

动和搜索,从而开发出新的工具,并通过新的函数对数据文件进行处理。源代码交叉引用检查软件

ctags就是一个这样的好例子,它把程序中的符号位置信息以规则表达式的形式记录下来供检索程序

使用。

7. 灵活性

因为无法预测一个不太聪明的用户会怎样使用程序,因此在进行程序设计时,要尽可能地增加

灵活性,尽量避免给数据域长度或者记录条数加上限制。同时如果可能,应尽量编写能够响应网络

※ 16 ※

w

w

c

.

w

o

o

b

n

e

n

k

.

t

o

o

e

n

k

.

t

w

w

c

w

.

访问的程序,使它既能够跨网络运行又能够在本地单机上运行。而Linux程序具备这一特质。比如:

Linux系统下的Ftp、samba等网络服务程序。

o

t

e

n

k

.

7 Linux下C语言编程风格

如果只是在编写一些小的练习程序,程序只有一两百行长的话,编程风格可能并不重要。然而,

如果和许多人一起进行开发工作,或者,希望在过一段时间之后,还能够正确理解自己的程序的话,

就必须养成良好的编程习惯。在诸多编程习惯当中,编程风格是重要的一项内容。有些程序员编写

的程序由于没有很好的缩进及顺序,让人看起来直皱眉头。编写干净美观的代码,不仅仅使代码更

容易阅读,还能使代码成为一件艺术品。

良好的编程风格可以在许多方面帮助开发人员。如果程序非常杂乱,大概看一眼就令人晕头转

向了。编程风格能体现一个程序员的综合素质。Linux上的编程主要有两种编程风格:GNU风格和

Linux核心风格,下面将分别介绍。

7.1 基于GNU的编程风格

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

.

c

o

o

b

n

(1)函数开头的左花括号放到最左边,避免把任何其他的左花括号、左括号或者左方括号放到

最左边。

(2)尽力避免让两个不同优先级的操作符出现在相同的对齐方式中。

(3)每个程序都应该有一段简短的说明其功能的注释开头。

(4)为每个函数书写注释,以说明函数做了些什么,需要哪些种类的参数,参数可能值的含义

以及用途。

(5)不要在声明多个变量时跨行。在每一行中都以一个新的声明开头。

(6)当在一个if语句中嵌套了另一个if-else语句时,应用花括号把if-else括起来。

t

e

n

k

.

w

w

w

b

n

c

.

c

.

w

w

w

(7)要在同一个声明中同时说明结构标识和变量,或者结构标识和类型定义(typedef)。

(8)尽力避免在if的条件中进行赋值。

(9)请在名字中使用下划线以分隔单词,尽量使用小写;把大写字母留给宏和枚举常量,以及

根据统一的惯例使用的前缀。

(10)使用一个命令行选项时,给出的变量应该在选项含义的说明之后,而不是选项字符之后。

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

7.2 Linux内核编程风格

在Linux中,经常看到的是定义非常简单的函数接口和变量名称。在Linux内核的源代码中,

可以看到Linux内核源代码的编码风格说明(/ Documentation/CodingStyle)。UNIX系统的一个特点

是设计精巧,并遵守积木式原则。C语言最初来自UNIX操作系统,与UNIX的设计原则一样,C

语言被广泛认可和使用的一个重要原因是它的灵活性以及简洁性。因此,在利用C语言编写程序时,

始终应当符合其简洁的设计原则,而不应当使用非常复杂的变量命名方法。Linus为Linux内核定义

的C语言编码风格要点如下:

(1)缩进时,使用长度为8个字符宽的Tab键。如果程序的缩进超过3级,则应考虑重新设计

程序。

理由是:缩进的大小是为了清楚的定义一个块的开始和结束。特别是当使用者已经在计算机前

面呆了20多个小时了以后,将会发现一个大的缩进格式使得对程序的理解更容易。

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

(2)大括号的位置。除函数的定义体外,应当将左大括号放在行尾,而将右大括号放在行首。

函数的定义体应将左右大括号放在行首。如下所示:

int function(int a, int b)

{

if (a == b) {

...

} else if (a > b) {

w

w

c

.

w

o

o

b

n

e

n

k

.

t

※ 17 ※

o

o

e

n

k

.

t

w

w

c

w

.

o

t

e

n

k

.

.

c

o

o

b

n

...

} else {

...

}

do {

...

} while (condition);

return 0;

}

理由:这种大括号的放置方法减小了空行的数量,但却没有减少可读性。于是,在屏幕大小受

到限制的时候,就可以有更多的空行来写些注释了。

(3)应采用简洁的命名方法。对变量名,不赞成使用大小写混写的形式,但鼓励使用描述性的

名称;尽可能不使用全局变量;不采用匈牙利命名法表示变量的类型;采用短小精悍的名称表示局

部变量;保持函数短小,从而避免使用过多的局部变量。局部变量的数量不应该超过5-10个,否则

有可能会出错。重新考虑这个函数,将他们分割成更小的函数。

(4)保持函数短小精悍。函数应该短小而迷人,它应只覆盖一到两个屏幕(80*24一屏),并

且只作一件事情,而且将它做好。然而,假如要写一个很复杂的函数,而且已经估计到假如一般人

读这个函数,他可能都不知道这个函数在说些什么,这个时候,使用具有描述性名字的有帮助的函

数。

(5)不应过分强调注释的作用,应尽量采用好的编码风格而不是添加过多的注释。通常情况下,

注释是说明代码做些什么,而不是怎么做。而且,要试图避免将注释插在一个函数体里。

b

n

c

.

w

w

w

k

o

o

k

o

o

t

e

.

n

t

e

n

k

.

w

w

w

b

n

c

.

c

.

w

w

w

o

o

b

n

n

k

.

e

t

b

n

c

.

w

w

w

k

o

o

t

e

.

n

w

w

w

o

o

b

n

c

.

t

e

n

k

.

b

n

c

.

w

w

w

w

w

k

o

o

t

e

.

n

n

c

w

.

k

o

o

b

w

w

c

.

w

o

o

b

n

e

n

k

.

t

※ 18 ※

o

o

e

n

k

.

t

w

w

c

w

.