Linux 环境下的C语言编程_第1页
Linux 环境下的C语言编程_第2页
Linux 环境下的C语言编程_第3页
Linux 环境下的C语言编程_第4页
Linux 环境下的C语言编程_第5页
已阅读5页,还剩98页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Linux Linux 环境下的环境下的 C C语言编程语言编程第一部分第一部分: : Linux Linux下的下的C C编程实战之开编程实战之开发平台搭建发平台搭建准备工作准备工作n建议在建议在PC内存足够大的情况下,不要直接安装内存足够大的情况下,不要直接安装Linux操作系统,最好把它安装在运行操作系统,最好把它安装在运行VMWare虚拟机软件虚拟机软件的的Windows平台上,如下图:平台上,如下图: 1. Vim1. Vim和和EmacsEmacs编辑器编辑器n在在Linux平台下,可用任意一个文本编辑工具编辑源代码。平台下,可用任意一个文本编辑工具编辑源代码。nVim(vi im

2、prove)是)是Linux下功能强大的编辑器,是由下功能强大的编辑器,是由UNIX系统下的传统文本编辑器系统下的传统文本编辑器vi发展而来,是发展而来,是vi的一个增强的一个增强版本,有彩色和高亮等特性,对编程有很大帮助。主菜单版本,有彩色和高亮等特性,对编程有很大帮助。主菜单-编编程程-vi Improved命令来运行命令来运行x-windows下的下的vim。nEmacs即即Editor MACroS(编辑器宏编辑器宏)的缩写,是一种强大的的缩写,是一种强大的文本编辑器,在程序员和其他以技术工作为主的计算机用户文本编辑器,在程序员和其他以技术工作为主的计算机用户中广受欢迎。中广受欢迎。使

3、用使用vimvim编辑编辑helloworldhelloworld程序程序使用使用emacsemacs编辑编辑helloworldhelloworld程序程序2.2.GCC编译器编译器nGCC是是Linux平台下最重要的开发工具,它是平台下最重要的开发工具,它是GNU的的C和和C+编译器,其基本用法为:编译器,其基本用法为:ngcc options filenames 该命令按编译选项(参数该命令按编译选项(参数options)指定的操作对给)指定的操作对给定的文件进行编译处理。定的文件进行编译处理。n编译一输出编译一输出“Hello World”的程序:的程序: main() printf(

4、Hello Worldn);2.2.GCC编译器编译器n最简单的编译方法是不指定任何编译选项,它会为目标最简单的编译方法是不指定任何编译选项,它会为目标程序生成默认的文件名程序生成默认的文件名 a.outgcc o选项:编译来为将产生的可执行文件指定一个文件名。选项:编译来为将产生的可执行文件指定一个文件名。例如,将上述名为例如,将上述名为helloworld.c的的C程序编译为名叫程序编译为名叫helloworld的可执行文件,输入如下命令:的可执行文件,输入如下命令:gcc -o helloworld helloworld.c2.2.GCC编译器编译器- -常用选项常用选项nc选项:告诉选

5、项:告诉GCC仅把源代码仅把源代码(.c文件文件)编译为目标代码编译为目标代码(.o文件文件)而跳过汇编和连接的步骤;它能使编译多个而跳过汇编和连接的步骤;它能使编译多个C程序时的速度更程序时的速度更快且容易管理。例如用户将已编辑好的快且容易管理。例如用户将已编辑好的test.c文件编译成名为文件编译成名为test.o的目标文件。可以使用命令的目标文件。可以使用命令 gcc -c s选项:告诉选项:告诉GCC 在为在为 C代码产生了汇编语言文件后停止编译。代码产生了汇编语言文件后停止编译。GCC 产生的汇编语言文件的缺省扩展名是产生的汇编语言文件的缺省扩展名是.s。将生成。将生成hellowo

6、rld.c的汇编代码,使用的是的汇编代码,使用的是AT&T汇编。用汇编。用emacs打开打开汇编代码如下图。汇编代码如下图。用用emacs打开的打开的Hello.c的汇编代码的汇编代码2.2.GCC编译器编译器- -常用选项常用选项nE选项:指示编译器仅对输入文件进行预处理,但不汇编和连接选项:指示编译器仅对输入文件进行预处理,但不汇编和连接nO(-O1)选项:告诉)选项:告诉GCC对源代码进行基本优化从而使得程序对源代码进行基本优化从而使得程序执行地更快;而执行地更快;而-O2选项告诉选项告诉GCC产生尽可能小和尽可能快的代产生尽可能小和尽可能快的代码。使用码。使用-O2选项编译的速

7、度比使用选项编译的速度比使用-O时慢,但产生的代码执行时慢,但产生的代码执行速度会更快。速度会更快。nWall 选项:显示附加的警告信息。例如在上述程序中去掉选项:显示附加的警告信息。例如在上述程序中去掉 return 0;语句,之后重新编译语句,之后重新编译 gcc Wall o hello hello.c将得到的警告信息:将得到的警告信息:hello.c : 5:warning:control reaches end of non-void function3. 3. GDB 调试器调试器nGCC用于编译程序,而用于编译程序,而Linux的另一个的另一个GNU工具工具gdb则用于调试程则用

8、于调试程序。序。gdb是一个用来调试是一个用来调试C和和C+程序的强力调试器,通过它进行程序的强力调试器,通过它进行一系列调试工作。一系列调试工作。ngdb主要提供一下功能主要提供一下功能:n监视程序中变量的值得变化监视程序中变量的值得变化n设置断点,使程序在指定的代码上暂停执行,便于观察设置断点,使程序在指定的代码上暂停执行,便于观察n单步执行代码单步执行代码n分析崩溃程序产生的分析崩溃程序产生的core文件文件3. 3. GDB 调试器调试器ngdb最常用的命令如下最常用的命令如下nfile:装入想要调试的可执行文件。:装入想要调试的可执行文件。nkill:终止正在调试的程序。:终止正在调

9、试的程序。 nlist:列表显示源代码。:列表显示源代码。 nnext:执行一行源代码但不进入函数内部。:执行一行源代码但不进入函数内部。 nstep:执行一行源代码而且进入函数内部。:执行一行源代码而且进入函数内部。 nrun:执行当前被调试的程序:执行当前被调试的程序 nquit:终止:终止gdbnwatch:监视一个变量的值:监视一个变量的值 nbreak:在代码里设置断点,程序执行到这里时挂起:在代码里设置断点,程序执行到这里时挂起 3. 3. GDB 调试器调试器n举例说明怎样用举例说明怎样用GDB调试一个求调试一个求0+1+2+3+99的程序:的程序:/* Filename:sum

10、.c */main() int i, sum; sum = 0; for (i = 0; i 100; i+) sum + = i; printf(the sum of 1+2+.+ is %d, sum);3. 3. GDB 调试器调试器3. 3. GDB 调试器调试器n执行如下命令编译执行如下命令编译sum.c(加(加-g选项产生选项产生debug信息):信息): gcc g o sum 在命令行上键入在命令行上键入gdb sum并按回车键就可以开始调试并按回车键就可以开始调试sum了,了,再运行再运行run命令执行命令执行sum,屏幕上将看到如下内容:,屏幕上将看到如下内容: 3. 3.

11、 GDB 调试器调试器nlist命令:命令:list命令用于列出源代码,对上述程序运行命令用于列出源代码,对上述程序运行list,将,将出现如下画面(源代码被标行号):出现如下画面(源代码被标行号):3. 3. GDB 调试器调试器n根据列出的源程序,如果将断点设置在第根据列出的源程序,如果将断点设置在第4行,只需在行,只需在gdb 命令行提示符下键入如下命令设置断点:命令行提示符下键入如下命令设置断点:n(gdb)break 4nBreakpoint 1 at 0 x8048338:file sum.c line 4n这时再这时再run,程序会停止在第,程序会停止在第4行:行:nStarti

12、ng program:/root/sumnBreakpoint 1,main() at sum.c line 4n4 sum=03. 3. GDB 调试器调试器n设置断点的另一种语法是设置断点的另一种语法是 break ,它在进入,它在进入指定函数(指定函数(function)时停住。)时停住。n相反的,相反的,clear用于清除所有的已定义的断点用于清除所有的已定义的断点nclear 清除设置在函数上的断点;清除设置在函数上的断点;nclear 则清除设置在指定行上的断点。则清除设置在指定行上的断点。3. 3. GDB 调试器调试器nwatch命令:用于观查变量或表达式的值命令:用于观查变量

13、或表达式的值nwatch命令观查命令观查sum变量只需要运行:变量只需要运行:watch sumnwatch命令观查表达式:命令观查表达式:watch 为表达式(变量)为表达式(变量)expr设置一个观察点,变量表达式值设置一个观察点,变量表达式值有变化时,程序会停止执行。有变化时,程序会停止执行。n要观查当前设置的要观查当前设置的watch,可以使用,可以使用info watchpoints命令。命令。3. 3. GDB 调试器调试器nnext、step命令:命令:nnext、step用于单步执行,在执行的过程中,被用于单步执行,在执行的过程中,被watch变量的变化情况将实时呈现变量的变化

14、情况将实时呈现(分别显示分别显示Old value和和New value),如下图:,如下图:nnext、step命令的区别在于命令的区别在于step遇到函数调用,会遇到函数调用,会跳转到该函数定义的开始行去执行,而跳转到该函数定义的开始行去执行,而next则不则不进入到函数内部,它把函数调用语句当作一条普进入到函数内部,它把函数调用语句当作一条普通语句执行。通语句执行。4.Make4.Maken编译和连接的区别编译和连接的区别n编译器使用源码文件来产生某种形式的目标文件,在编编译器使用源码文件来产生某种形式的目标文件,在编译过程中,外部的符号参考并没有被解释或替换(即外译过程中,外部的符号参

15、考并没有被解释或替换(即外部全局变量和函数并没有被找到)。因此,在编译阶段部全局变量和函数并没有被找到)。因此,在编译阶段所报的错误一般都是语法错误。所报的错误一般都是语法错误。n连接器则用于连接目标文件和程序包,生成一个可执行连接器则用于连接目标文件和程序包,生成一个可执行程序。在连接阶段,一个目标文件中对别的文件中的符程序。在连接阶段,一个目标文件中对别的文件中的符号的参考被解释,如果有符号不能找到,会报告连接错号的参考被解释,如果有符号不能找到,会报告连接错误。误。4.Make4.Maken编译和连接的一般步骤是:编译和连接的一般步骤是:n第一阶段把源文件一个一个的编译成目标文件,第一阶

16、段把源文件一个一个的编译成目标文件,n第二阶段把所有的目标文件加上需要的程序包连接第二阶段把所有的目标文件加上需要的程序包连接成一个可执行文件。成一个可执行文件。n这样的过程需要使用大量的这样的过程需要使用大量的gcc命令。而命令。而make则使从则使从大量源文件的编译和连接工作中解放出来,综合为一大量源文件的编译和连接工作中解放出来,综合为一步完成步完成。4.Make4.MakenGNU Make的主要工作是读进一个文本文件,称为的主要工作是读进一个文本文件,称为makefile。nmakefile文件记录了哪些文件(目的文件,目的文件文件记录了哪些文件(目的文件,目的文件不一定是最后的可执

17、行程序,它可以是任何一种文件)不一定是最后的可执行程序,它可以是任何一种文件)由哪些文件(依靠文件)产生,用什么命令来产生。由哪些文件(依靠文件)产生,用什么命令来产生。nMake依靠此依靠此makefile中的信息检查磁盘上的文件,如中的信息检查磁盘上的文件,如果目的文件的创建或修改时间比它的一个依靠文件旧果目的文件的创建或修改时间比它的一个依靠文件旧的话,的话,make就执行相应的命令,以便更新目的文件。就执行相应的命令,以便更新目的文件。4.Make4.Makenmakefile文件的编写文件的编写nmakefile文件是一个文本文件,用于描述整个项目和各个文件是一个文本文件,用于描述整

18、个项目和各个文件之间的依赖关系。它由多个规则组成。文件之间的依赖关系。它由多个规则组成。nmakefile文件的规则遵循以下结构文件的规则遵循以下结构n#remark 注释行注释行ntarget:file1 file2 二进制文件或者目标文件二进制文件或者目标文件ncommand1 命令命令ncommand2n4.Make4.Maken例如例如: 下面三个文件,下面三个文件,add.h用于声明用于声明add函数,函数,add.c提提供两个整数相加的函数体,而供两个整数相加的函数体,而main.c中调用中调用add函数:函数: /* filename:add.h */extern int add

19、(int i, int j);/* filename:add.c */int add(int i, int j) return i + j;/* filename:main.c */#include add.hmain() int a, b; a = 2; b = 3; printf(the sum of a+b is %d, add(a + b);怎样为上述三个文件产生怎样为上述三个文件产生makefile呢?呢?4.Make4.Maken为上述三个文件产生为上述三个文件产生makefile的方法如下:的方法如下: test : main.o add.o gcc main.o add.o -

20、o test main.o : main.c add.h gcc -c main.c -o main.o add.o : add.c add.h gcc -c add.c -o add.o 4.Make4.Maken上述上述makefile文件的含义文件的含义n利用利用add.c和和add.h文件执行文件执行gcc -c add.c -o add.o命令产生命令产生add.o目标代码。目标代码。n利用利用main.c和和add.h文件执行文件执行gcc -c main.c -o main.o命令命令产生产生main.o目标代码。目标代码。n最后利用最后利用main.o和和add.o文件(两个模

21、块的目标代码)执文件(两个模块的目标代码)执行行gcc main.o add.o -o test命令产生可执行文件命令产生可执行文件test。n可以使用可以使用gcc -MM main.c自动寻找源文件中的头文件,并自动寻找源文件中的头文件,并形成依赖关系。形成依赖关系。n输出为:输出为:main.o main.c add.h4.Make4.Maken可在可在makefile中加入变量。另外,环境变量在中加入变量。另外,环境变量在make过程中过程中也被解释成也被解释成make的变量。这些变量是大小写敏感的,一般的变量。这些变量是大小写敏感的,一般使用大写字母。使用大写字母。n要定义一个变量,

22、只需要在一行的开始写下这个变量的名要定义一个变量,只需要在一行的开始写下这个变量的名字,后面跟一个字,后面跟一个=号,再跟变量的值。引用变量的方法是写号,再跟变量的值。引用变量的方法是写一个一个$符号,后面跟(变量名)。符号,后面跟(变量名)。4.Make4.Maken把前面的把前面的 makefile 利用变量重写一遍(并假设使用利用变量重写一遍(并假设使用-Wall -O g编译选项):编译选项):nOBJS = main.o add.onCC = gccnCFLAGS = -Wall -O -gntest : $(OBJS)n$(CC) $(OBJS) -o testnmain.o :

23、main.c add.hn$(CC) $(CFLAGS) -c main.c -o main.onadd.o : add.c add.hn$(CC) $(CFLAGS) -c add.c -o add.o 4.Make4.Makenmakefile 中还可定义清除(中还可定义清除(clean)目标,可用来清除)目标,可用来清除编译过程中产生的中间文件,例如在上述编译过程中产生的中间文件,例如在上述makefile文件文件中添加下列代码:中添加下列代码: nclean: rm -f *.on运行运行make clean时,将执行时,将执行rm -f *.o命令,删除所有编命令,删除所有编译过程中

24、产生的中间文件。译过程中产生的中间文件。4.Make4.MakenMake的运行的运行nGUN make默认在当前的目录下一次查找默认在当前的目录下一次查找GUNmake文件,文件,Makefile文件和文件和makefile文件,文件,找到后读取文件执行。找到后读取文件执行。n给给make命令指定一个特殊名字的命令指定一个特殊名字的makefile文件文件nmake f hchen.mk4.Make4.Maken自己动手编写自己动手编写makefile仍然是很复杂和烦琐的,而且很仍然是很复杂和烦琐的,而且很容易出错。因此,容易出错。因此,GNU也提供了也提供了Automake和和Autoco

25、nf来辅助快速自动产生来辅助快速自动产生makefile。4.Make4.Maken使用使用autoconf和和automake来进行自动化配置和生成来进行自动化配置和生成Makefile的流程可以概括如下:的流程可以概括如下:n运行运行autoscan命令。命令。n将将configure.scan文件重命名为文件重命名为configure.in,并修改,并修改configure.in文件。文件。n运行运行aclocal命令得到命令得到aclocal.m4文件。文件。n运行运行autoconf命令得到命令得到configure文件。文件。n在工程目录下新建在工程目录下新建Makefile.am

26、文件,如果存在子目录,文件,如果存在子目录,子目录中也要创建此文件。子目录中也要创建此文件。n将将/usr/share/automake-1.X/目录下的目录下的depcomp和和compile文件复制到需要处理目录下。文件复制到需要处理目录下。n运行运行automake -a命令得到命令得到Makefile.in文件。文件。n运行运行./configure脚本脚本 4.Make4.Maken从例子程序从例子程序helloworld开始。过程如下:开始。过程如下:n新建三个文件:新建三个文件: helloworld.cconfigure.inMakefile.amn然后执行然后执行 acloc

27、al; autoconf; automake -add-missing; ./configure; make; ./helloworld nMakefile被产生出来,而且可以将被产生出来,而且可以将helloworld.c编译通编译通过。过。小结小结n本部分主要阐述了本部分主要阐述了Linux程序的编写、编译、调试方程序的编写、编译、调试方法及法及make,实际上是引导学习怎样在,实际上是引导学习怎样在Linux下编程,下编程,为后续章节做好准备。为后续章节做好准备。第二部分第二部分 LinuxLinux下的下的C C编程实战之编程实战之文件系统编程文件系统编程 LinuxLinux平台下文

28、件编程平台下文件编程n在在Linux平台下对文件编程可以使用两类函数:平台下对文件编程可以使用两类函数:nLinux操作系统文件操作系统文件API;nC语言语言I/O库函数。库函数。 n前者依赖于前者依赖于Linux系统调用,后者实际上与操作系统是系统调用,后者实际上与操作系统是独立的,因为在任何操作系统下,使用独立的,因为在任何操作系统下,使用C语言语言I/O库函库函数操作文件的方法都是相同的。数操作文件的方法都是相同的。 1. Linux1. Linux文件文件API-API-创建创建n创建创建nint create(const char *filename, mode_t mode);

29、参数参数mode指定新建文件的存取权限,它同指定新建文件的存取权限,它同umask一起决定文件的最终权限(一起决定文件的最终权限(mode&umask).numask代表了文件在创建时需要去掉的一些存取权代表了文件在创建时需要去掉的一些存取权限。限。umask可通过系统调用可通过系统调用umask()来改变:来改变: int umask(int newmask); 该调用将该调用将umask设置为设置为newmask,然后返回旧,然后返回旧的的umask,它只影响读、写和执行权限。,它只影响读、写和执行权限。1. Linux1. Linux文件文件API-API-创建创建nmode可以

30、是以下情况的组合,可以是以下情况的组合,可以通过上述宏进行可以通过上述宏进行“或或”逻辑产生标志。逻辑产生标志。 标志标志含义含义S_IRUSR 用户可以读用户可以读 S_IWUSR 用户可以写用户可以写 S_IXUSR 用户可以执行用户可以执行 S_IRWXU 用户可以读、写、执行用户可以读、写、执行 S_IRGRP 组可以读组可以读 S_IWGRP 组可以写组可以写S_IXGRP 组可以执行组可以执行 S_IRWXG 组可以读写执行组可以读写执行 1. Linux1. Linux文件文件API-API-创建创建nmode可以是以下情况的组合,可以是以下情况的组合,可以通过上述宏进行可以通过

31、上述宏进行“或或”逻辑产生标志。逻辑产生标志。标志标志含义含义S_IROTH其他人可以读其他人可以读S_IWOTH其他人可以写其他人可以写S_IXOTH其他人可以执行其他人可以执行S_IRWXO其他人可以读、写、执行其他人可以读、写、执行S_ISUID设置用户执行设置用户执行IDS_ISGID设置组的执行设置组的执行ID1. Linux1. Linux文件文件API-API-创建创建n用数字来表示:用数字来表示:Linux总共用总共用5个数字来表示文件的各个数字来表示文件的各种权限:种权限:n第一位表示设置用户第一位表示设置用户ID;n第二位表示设置组第二位表示设置组ID;n第三位表示用户自己

32、的权限位;第三位表示用户自己的权限位;n第四位表示组的权限;第四位表示组的权限;n最后一位表示其他人的权限。每个数字可以取最后一位表示其他人的权限。每个数字可以取1(执执行权限行权限)、2(写权限写权限)、4(读权限读权限)、0(无无)或者是这或者是这些值的和。些值的和。1. Linux1. Linux文件文件API-API-创建创建n用数字来表示:用数字来表示:n例如,要创建一个用户可读、可写、可执行,但是例如,要创建一个用户可读、可写、可执行,但是组没有权限,其他人可以读、可以执行的文件,并组没有权限,其他人可以读、可以执行的文件,并设置用户设置用户ID位。位。n应该使用的模式是应该使用的

33、模式是1(设置用户设置用户ID)、0(不设置组不设置组ID)、7(1+2+4,读、写、执行,读、写、执行)、0(没有权限没有权限)、5(1+4,读、,读、执行执行)即即10705 1. Linux1. Linux文件文件API-API-打开打开n打开打开nint open(const char *pathname, int flags);nint open(const char *pathname, int flags, mode_t mode); n如果文件打开成功,如果文件打开成功,open函数会返回一个文件描述符,函数会返回一个文件描述符,以后对该文件的所有操作就可以通过对这个文件描述符

34、以后对该文件的所有操作就可以通过对这个文件描述符进行操作来实现。进行操作来实现。nopen函数有两个形式,其中函数有两个形式,其中pathname是要打开的文件名是要打开的文件名(包含路径名称,缺省是认为在当前路径下面包含路径名称,缺省是认为在当前路径下面) 。1. Linux1. Linux文件文件API-API-打开打开n打开打开nflags可以是下面的一个值或者是几个值的组合,可以是下面的一个值或者是几个值的组合,O_RDONLY、O_WRONLY、O_RDWR三个标志只能三个标志只能使用任意的一个使用任意的一个。1. Linux1. Linux文件文件API-API-打开打开n打开打开

35、n如果使用了如果使用了O_CREATE标志,则使用的函数是标志,则使用的函数是int open(const char *pathname,int flags,mode_t mode); 这时这时要指定要指定mode标志,用来表示文件的访问权限。以标志,用来表示文件的访问权限。以O_CREAT为标志的为标志的open实际上实现了文件创建的功能。实际上实现了文件创建的功能。n例如:例如: open(test, O_CREAT, 10705); open(test, O_CREAT, S_IRWXU | S_IROTH | S_IXOTH | S_ISUID );1. Linux1. Linux文件

36、文件API-API-读写读写n读写读写nLinux中提供文件读写的系统调用是中提供文件读写的系统调用是read、write函数:函数: int read(int fd, const void *buf, size_t length); int write(int fd, const void *buf, size_t length);n参数参数buf为指向缓冲区的指针,为指向缓冲区的指针,length为缓冲区的大为缓冲区的大小(以字节为单位)。小(以字节为单位)。1. Linux1. Linux文件文件API-API-读写读写nint read(int fd, const void *buf,

37、 size_t length);n函数函数read实现从文件描述符实现从文件描述符fd所指定的文件中读取所指定的文件中读取length个字节到个字节到buf所指向的缓冲区中,返回值为实际读所指向的缓冲区中,返回值为实际读取的字节数。取的字节数。nint write(int fd, const void *buf, size_t length);n函数函数write实现将把实现将把length个字节从个字节从buf指向的缓冲区中写指向的缓冲区中写到文件描述符到文件描述符fd所指向的文件中,返回值为实际写入的所指向的文件中,返回值为实际写入的字节数。字节数。1. Linux1. Linux文件文件

38、API-API-定位定位n定位:定位:n对于随机文件,我们可以随机的指定位置读写,使用如对于随机文件,我们可以随机的指定位置读写,使用如下函数进行定位:下函数进行定位: int lseek(int fd, offset_t offset, int whence);nlseek()将文件读写指针相对将文件读写指针相对whence移动移动offset个字节。操个字节。操作成功时,返回文件指针相对于文件头的位置。参数作成功时,返回文件指针相对于文件头的位置。参数whence可使用下述值:可使用下述值:nSEEK_SET:相对文件开头:相对文件开头nSEEK_CUR:相对文件读写指针的当前位置:相对文

39、件读写指针的当前位置nSEEK_END:相对文件末尾:相对文件末尾1. Linux1. Linux文件文件API-API-定位定位n定位:定位:noffset可取负值,例如下述调用可将文件指针相对当前位可取负值,例如下述调用可将文件指针相对当前位置向前移动置向前移动5个字节:个字节: lseek(fd, -5, SEEK_CUR);n由于由于lseek函数的返回值为文件指针相对于文件头的位置,函数的返回值为文件指针相对于文件头的位置,因此下列调用的返回值就是文件的长度:因此下列调用的返回值就是文件的长度: lseek(fd, 0, SEEK_END);1. Linux1. Linux文件文件A

40、PI-API-关闭关闭n关闭关闭n当操作完成以后,要关闭文件,只要调用当操作完成以后,要关闭文件,只要调用close即可,即可,其 中其 中 f d 是 要 关 闭 的 文 件 描 述 符 :是 要 关 闭 的 文 件 描 述 符 : int close(int fd);1. Linux1. Linux文件文件API-API-编程实例编程实例n例程:编写一个程序,在当前目录下创建用户可读写例程:编写一个程序,在当前目录下创建用户可读写文件文件“hello.txt”,在其中写入,在其中写入“Hello, software weekly”,关闭该文件。再次打开该文件,读取其中的,关闭该文件。再次打

41、开该文件,读取其中的内容并输出在屏幕上。内容并输出在屏幕上。n#include /类型类型n#include /获取文件属性获取文件属性n#include /文件描述词操作文件描述词操作n#include #define LENGTH 100nmain()int fd, len;char strLENGTH; fd = open(“hello.txt”, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); /* 创建并打开文件创建并打开文件 ,以读写的方式打开,用户可,以读写的方式打开,用户可以读、用户可以写以读、用户可以写*/1. Linux1. Linux文件文件A

42、PI-API-编程实例编程实例nif (fd) write(fd, Hello, Software Weekly, strlen(Hello, software weekly); /* 写入写入Hello, software weekly字符串字符串 */close(fd);nfd = open(“hello.txt”, O_RDWR); /以读写方式打开以读写方式打开 len = read(fd, str, LENGTH); /* 读取文件内容读取文件内容 */strlen = 0;printf(%sn, str);close(fd); 1. Linux1. Linux文件文件API-API

43、-编程实例编程实例1. Linux1. Linux文件文件API-API-编程实例编程实例n编译并运行,执行结果如下编译并运行,执行结果如下nrootdl root#gcc g o hello ./rootdl root# ./hellonHello,software weekly3.C3.C语言库函数语言库函数nC库函数的文件操作实际上是独立于具体的操作系统库函数的文件操作实际上是独立于具体的操作系统平台的,不管是在平台的,不管是在DOS、Windows、Linux还是在还是在VxWorks中都是这些函数中都是这些函数.3.C3.C语言库函数语言库函数- -创建和打开创建和打开n创建和打开创

44、建和打开nFILE *fopen(const char *path, const char *mode);nfopen()实现打开指定文件,实现打开指定文件,参数参数path字符串包含欲字符串包含欲打开的文件路径及文件名打开的文件路径及文件名 ,mode为打开模式为打开模式.n返回值:文件指针名。必须被说明为返回值:文件指针名。必须被说明为FILE类型的指类型的指针变量针变量 。3.C3.C语言库函数语言库函数- -创建和打开创建和打开nC语言中支持的打开模式如下表,其中语言中支持的打开模式如下表,其中b用于区分二进制文件用于区分二进制文件和文本文件,在和文本文件,在DOS、Windows系统

45、中是有区分的,但系统中是有区分的,但Linux不区分二进制文件和文本文件。不区分二进制文件和文本文件。标志标志含义含义r, rb以只读方式打开以只读方式打开w, wb以只写方式打开。如果文件不存在,则创建该文件,否以只写方式打开。如果文件不存在,则创建该文件,否则文件被截断则文件被截断a, ab以追加方式打开。如果文件不存在,则创建该文件以追加方式打开。如果文件不存在,则创建该文件r+, r+b, rb+以读写方式打开以读写方式打开+, w+b, wh+以读写方式打开。如果文件不存在时,创建新文件,否以读写方式打开。如果文件不存在时,创建新文件,否则文件被截断则文件被截断a+, a+b, ab

46、+以读和追加方式打开。如果文件不存在,创建新文件以读和追加方式打开。如果文件不存在,创建新文件3.C3.C语言库函数语言库函数- -读写读写n读写:读写:C库函数支持以字符、字符串等为单位,支持库函数支持以字符、字符串等为单位,支持按照某中格式进行文件的读写,这一组函数为:按照某中格式进行文件的读写,这一组函数为:nint fgetc(FILE *stream); 从流中读一个字符从流中读一个字符nint fputc(int c, FILE *stream);送一个字符到流中送一个字符到流中nchar *fgets(char *s, int n, FILE *stream);从流中读从流中读取

47、一字符串取一字符串 nint fputs(const char *s, FILE *stream);送一个字符送一个字符串到流中串到流中3.C3.C语言库函数语言库函数- -读写读写nint fprintf(FILE *stream, const char *format, .);n传送格式化输出到一个文件中,成功时返回转换的传送格式化输出到一个文件中,成功时返回转换的字节数,失败时返回一个负数。字节数,失败时返回一个负数。 fprintf( stream, %s%c, s, c ); fprintf( stream, %dn, i ); nint fscanf (FILE *stream,

48、const char *format, .);n从一个流中执行格式化输入从一个流中执行格式化输入 if (fscanf(stdin, %d, &i) printf(The integer read was: %dn,i); 3.C3.C语言库函数语言库函数- -读写读写n读写:读写:nsize_t fread(void *ptr, size_t size, size_t n, FILE *stream);nsize_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream);nfread()实现从流实现从流stream

49、中读取中读取n个字段,每个字段为个字段,每个字段为size字节,并将读取的字段放入字节,并将读取的字段放入ptr所指的字符数组中,所指的字符数组中,返回实际已读取的字段数。返回实际已读取的字段数。nwrite()实现从缓冲区实现从缓冲区ptr所指的数组中把所指的数组中把n个字段写到个字段写到流流stream中,每个字段长为中,每个字段长为size个字节,返回实际写入个字节,返回实际写入的字段数。的字段数。3.C3.C语言库函数语言库函数- -定位定位n定位定位 :C库函数还提供了读写过程中的定位能力,这些函库函数还提供了读写过程中的定位能力,这些函数包括:数包括:nint fgetpos(FI

50、LE *stream, fpos_t *pos); /将文件流的文件位置指示符存储在将文件流的文件位置指示符存储在pos变量中变量中nint fsetpos(FILE *stream, const fpos_t *pos);/将文件指针定位在将文件指针定位在pos指定的位置上指定的位置上 n返回值:成功返回返回值:成功返回0,否则返回非,否则返回非0。n#include nvoid main( void )nn FILE *fp;n fpos_t pos;n char buffer50;n if( (fp = fopen( test.txt, rb ) = NULL ) /*以只读方以只读方式

51、打开名为式打开名为test.txt的文件的文件*/n printf( Trouble opening filen );n elsen n pos = 10; /*设置设置pos值值*/n if( fsetpos( fp, &pos ) != 0 ) /*应用应用fsetpos函数将文件指函数将文件指针针fp按照按照pos指定的位置在文件中定位指定的位置在文件中定位*/n perror( fsetpos error );nelse n /*从新定位的文件指针开始读取从新定位的文件指针开始读取16个字符到个字符到buffer缓冲区缓冲区*/nfread( buffer, sizeof( c

52、har ), 16, fp );nprintf( 16 bytes at byte %ld: %.16sn, pos, buffer ); /*显显示结果示结果*/n n n fclose( fp );n 3.C3.C语言库函数语言库函数- -定位定位n首先,程序以只读方式打开名为首先,程序以只读方式打开名为test.txt的文件。在这里,的文件。在这里,test.txt文件中已存入字符串文件中已存入字符串This is a test for testing the function of fsetpos.n将将pos设置为设置为10。应用。应用fsetpos函数将文件指针函数将文件指针fp按

53、照按照pos指定的位置在文件中定位。这样文件指针指定的位置在文件中定位。这样文件指针fp指向字符串指向字符串中中test的字母的字母t。n再从新定位的文件指针开始读取再从新定位的文件指针开始读取16个字符到个字符到buffer缓冲缓冲区,也就是说读取字符串区,也就是说读取字符串test for testing到缓冲区到缓冲区buffer。n最后显示结果:最后显示结果:16 bytes at byte 10: test for testing 3.C3.C语言库函数语言库函数- -定位定位nint fseek(FILE *stream, long offset, int whence);nstr

54、eam为文件指针为文件指针noffset为偏移量,整数表示正向偏移,负数为负向偏移为偏移量,整数表示正向偏移,负数为负向偏移nwhence设定从文件的哪里开始偏移,可能取值为:设定从文件的哪里开始偏移,可能取值为:nSEEK_SET: 文件开头文件开头 0nSEEK_CUR: 当前位置当前位置 1nSEEK_END: 文件结尾文件结尾 2nfseek(fp,100L,0);把把fp指针移动到离文件开头指针移动到离文件开头100字节处;字节处;nfseek(fp,100L,1);把把fp指针移动到离文件当前位置指针移动到离文件当前位置100字节处;字节处;nfseek(fp,100L,2);把把

55、fp指针退回到离文件结尾指针退回到离文件结尾100字节处。字节处。3.C3.C语言库函数语言库函数- -关闭关闭n关闭:关闭:n利用利用C库函数关闭文件的操作:库函数关闭文件的操作: int fclose (FILE *stream);3.C3.C语言库函数语言库函数- -编程实例编程实例n例程:编写一个程序,在当前目录下创建用户可读写例程:编写一个程序,在当前目录下创建用户可读写文件文件“hello.txt”,在其中写入,在其中写入“Hello, software weekly”,关闭该文件。再次打开该文件,读取其中的,关闭该文件。再次打开该文件,读取其中的内容并输出在屏幕上。内容并输出在屏

56、幕上。n#include #define LENGTH 100nmain()FILE *fd;char strLENGTH;fd = fopen(hello.txt, w+); /* 创建并打开文件创建并打开文件 */if (fd)fputs(Hello, Software Weekly, fd); /* 写入写入Hello, software weekly字符串字符串 */fclose(fd);fd = fopen(hello.txt, r);fgets(str, LENGTH, fd); /* 读取文件内容读取文件内容 */printf(%sn, str);fclose(fd);3.3.小

57、结小结nLinux提供的虚拟文件系统为多种文件系统提供了统提供的虚拟文件系统为多种文件系统提供了统一的接口,一的接口,Linux的文件编程有两种途径:的文件编程有两种途径:n基于基于Linux系统调用;系统调用;n基于基于C库函数库函数n这两种编程所涉及到文件操作有新建、打开、读写和这两种编程所涉及到文件操作有新建、打开、读写和关闭,对随机文件还可以定位。关闭,对随机文件还可以定位。 第二部分第二部分 LinuxLinux下的下的C C编程实战之进编程实战之进程控制与进程通信编程程控制与进程通信编程 1. 1.进程的基本进程的基本概念概念n进程是具有一定功能的程序,是关于一个数据集合的一次进程

58、是具有一定功能的程序,是关于一个数据集合的一次执行过程。多个进程可以同时运行。执行过程。多个进程可以同时运行。nLinux进程在内存中包含三部分数据:进程在内存中包含三部分数据:n代码段:存放了程序的代码,代码段可以为机器中运行代码段:存放了程序的代码,代码段可以为机器中运行同一程序的数个进程共享。同一程序的数个进程共享。n堆栈段:存放的是子程序(函数)的返回地址、子程序堆栈段:存放的是子程序(函数)的返回地址、子程序的参数及程序的局部变量。的参数及程序的局部变量。n数据段:存放程序的全局变量、常数以及动态数据分配数据段:存放程序的全局变量、常数以及动态数据分配的数据空间。堆栈段和数据段不能为

59、运行同一程序的数的数据空间。堆栈段和数据段不能为运行同一程序的数个进程共享。个进程共享。2.2.进程控制进程控制- -进程的创建进程的创建n(1)派生进程)派生进程n系统调用系统调用fork用于派生一个进程,其说明如下:用于派生一个进程,其说明如下: #include pid_t fork(void); pid_t vfork(void);n调用调用fork时,系统创建一个与当前进程(父进程)时,系统创建一个与当前进程(父进程)相同的新进程(子进程)。子进程是父进程的一个相同的新进程(子进程)。子进程是父进程的一个复制,子进程拷贝父进程的数据段、代码段复制,子进程拷贝父进程的数据段、代码段2.

60、2.进程控制进程控制- -进程的创建进程的创建nfork调用将执行两次返回,它将从父进程和子进程中调用将执行两次返回,它将从父进程和子进程中分别返回。分别返回。n从父进程返回时的返回值为子进程的从父进程返回时的返回值为子进程的PID,而从子,而从子进程返回时的返回值为进程返回时的返回值为0,并且返回都将执行,并且返回都将执行fork之之后的语句。调用出错时,返回值为后的语句。调用出错时,返回值为-1#include#include#includeint main( ) pid_t pid; pid=fork(); if(pid)0) printf(“fork error!n”); exit(1); else if(pid=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论