C语言程序设计CProgramming下课件

上传人:鲁** 文档编号:570811388 上传时间:2024-08-06 格式:PPT 页数:103 大小:1.35MB
返回 下载 相关 举报
C语言程序设计CProgramming下课件_第1页
第1页 / 共103页
C语言程序设计CProgramming下课件_第2页
第2页 / 共103页
C语言程序设计CProgramming下课件_第3页
第3页 / 共103页
C语言程序设计CProgramming下课件_第4页
第4页 / 共103页
C语言程序设计CProgramming下课件_第5页
第5页 / 共103页
点击查看更多>>
资源描述

《C语言程序设计CProgramming下课件》由会员分享,可在线阅读,更多相关《C语言程序设计CProgramming下课件(103页珍藏版)》请在金锄头文库上搜索。

1、C语言程序设计 (C Programming)辽宁科技大学下C语言程序设计 (C Programming)第第7章章 构造数据类型构造数据类型第第8章章 编译预处理编译预处理第第9章章 文件文件C语言程序设计 (C Programming)辽宁科技大学C语言程序设计语言程序设计 (C Programming)1 1、掌握结构体类型、结构体变量、结构体数组、掌握结构体类型、结构体变量、结构体数组的定义和使用的定义和使用2 2、掌握结构体类型指针的概念和使用、掌握结构体类型指针的概念和使用3 3、掌握结构体作为函数的参数和返回值的使用、掌握结构体作为函数的参数和返回值的使用4 4、掌握共用体类型、

2、共用体变量的定义和使用、掌握共用体类型、共用体变量的定义和使用5 5、理解链表的概念和建立、理解链表的概念和建立6 6、了解枚举类型的定义和使用、了解枚举类型的定义和使用本章学习目标本章学习目标本章学习目标本章学习目标4C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型结构体数据类型 7.2 7.2 结构体与数组结构体与数组7.3 7.3 结构体与指针结构体与指针7.4 7.4 结构体与函数结构体与函数7.5 7.5 结构体与链表结构体与链表 7.6 7.6 共用体数据类型共用体数据类型7.7 7.7 枚举类型枚举类型7.8 7.8 类型定义符类型定义符T

3、ypedefTypedef5C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型结构体数据类型1. 1. 结构体类型结构体类型结构体类型结构体类型的定义的定义的定义的定义2. 2. 结构体变量的结构体变量的结构体变量的结构体变量的定义定义定义定义3. 3. 结构体变量的结构体变量的结构体变量的结构体变量的初始化初始化初始化初始化4. 4. 结构体变量成结构体变量成结构体变量成结构体变量成员的引用员的引用员的引用员的引用“结构体结构体”是一种构造数据类型,结构体中包含的数据元素称为成是一种构造数据类型,结构体中包含的数据元素称为成员。那么如何定义一个结构体数据

4、类型呢?员。那么如何定义一个结构体数据类型呢?定义一个结构体类型的一般形式为:定义一个结构体类型的一般形式为:struct 结构体名结构体名类型说明符类型说明符1 成员名成员名1;类型说明符类型说明符2 成员名成员名2;. . .类型说明符类型说明符n 成员名成员名n; ;每个成员都是该结构体类型的一个组成部分,每个成员可以是一每个成员都是该结构体类型的一个组成部分,每个成员可以是一个基本数据类型,也可以是一个构造类型。成员名的命名应符合个基本数据类型,也可以是一个构造类型。成员名的命名应符合标识符的书写规范。标识符的书写规范。 6C语言程序设计语言程序设计 (C Programming)7.

5、1 7.1 结构体数据类型结构体数据类型1. 1. 结构体类型结构体类型结构体类型结构体类型的定义的定义的定义的定义2. 2. 结构体变量的结构体变量的结构体变量的结构体变量的定义定义定义定义3. 3. 结构体变量的结构体变量的结构体变量的结构体变量的初始化初始化初始化初始化4. 4. 结构体变量成结构体变量成结构体变量成结构体变量成员的引用员的引用员的引用员的引用struct student long no; char name15; char sex; int age; float score;在这个结构体定义中,在这个结构体定义中, student为结构体名,为结构体名,no、name、

6、sex、age和和score为该结构的为该结构的5个成员。其中个成员。其中no为长整型变量;为长整型变量;name为字符数组;为字符数组;sex为字符变量;为字符变量;age为整型变量;为整型变量;score 为实型变为实型变量。一般情况下,结构体名称用有一定意义的单词或单词的缩写量。一般情况下,结构体名称用有一定意义的单词或单词的缩写组合作为结构体的名称。结构体是一个整体,因此结构体中的每组合作为结构体的名称。结构体是一个整体,因此结构体中的每个成员不能脱离结构体单独使用。个成员不能脱离结构体单独使用。 7C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类

7、型结构体数据类型2. 2. 结构体变量结构体变量结构体变量结构体变量的定义的定义的定义的定义1. 1. 结构体类型的结构体类型的结构体类型的结构体类型的定义定义定义定义3. 3. 结构体变量的结构体变量的结构体变量的结构体变量的初始化初始化初始化初始化4. 4. 结构体变量成结构体变量成结构体变量成结构体变量成员的引用员的引用员的引用员的引用结构体类型一旦定义,即可进行变量定义。以结构体结构体类型一旦定义,即可进行变量定义。以结构体student为为例,凡定义为结构例,凡定义为结构student的变量都由上述的变量都由上述5个成员组成。成员名个成员组成。成员名可以与程序中变量名相同,两者互不干

8、扰。可以与程序中变量名相同,两者互不干扰。结构体变量定义有以下三种方法。结构体变量定义有以下三种方法。1先定义结构体类型,再定义结构体变量。先定义结构体类型,再定义结构体变量。例如:例如:struct student long no; char name15; char sex; int age; float score; struct student stu1,stu2;本例中定义了两个变量本例中定义了两个变量stu1和和stu2,它们都是,它们都是student结构体类结构体类型。型。struct student代表的是类型名,就如同定义实型变量时代表的是类型名,就如同定义实型变量时(如:

9、(如:float a,b;),其中其中 float 是类型名是一样的。结构体类型所是类型名是一样的。结构体类型所占有的内存字节数是所有成员的字节数的和。占有的内存字节数是所有成员的字节数的和。 8C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型结构体数据类型2. 2. 结构体变量结构体变量结构体变量结构体变量的定义的定义的定义的定义1. 1. 结构体类型的结构体类型的结构体类型的结构体类型的定义定义定义定义3. 3. 结构体变量的结构体变量的结构体变量的结构体变量的初始化初始化初始化初始化4. 4. 结构体变量成结构体变量成结构体变量成结构体变量成员的引

10、用员的引用员的引用员的引用2在定义结构体类型的同时定义结构体变量。在定义结构体类型的同时定义结构体变量。例如:例如:struct student long no; char name15; char sex; int age; float score; stu1,stu2;9C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型结构体数据类型2. 2. 结构体变量结构体变量结构体变量结构体变量的定义的定义的定义的定义1. 1. 结构体类型的结构体类型的结构体类型的结构体类型的定义定义定义定义3. 3. 结构体变量的结构体变量的结构体变量的结构体变量的初始化初始

11、化初始化初始化4. 4. 结构体变量成结构体变量成结构体变量成结构体变量成员的引用员的引用员的引用员的引用3直接定义结构体类型的变量。直接定义结构体类型的变量。例如:例如:struct long no; char name15; char sex; int age; float score;stu1,stu2;10C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型结构体数据类型3. 3. 结构体变量结构体变量结构体变量结构体变量的初始化的初始化的初始化的初始化1. 1. 结构体类型的结构体类型的结构体类型的结构体类型的定义定义定义定义2. 2. 结构体变量

12、的结构体变量的结构体变量的结构体变量的定义定义定义定义4. 4. 结构体变量成结构体变量成结构体变量成结构体变量成员的引用员的引用员的引用员的引用【例例7-1】外部结构体变量初始化外部结构体变量初始化#include struct student /*结构体定义结构体定义*/long no;char name15;char sex;int age;float score;stu1;struct student stu1=20080001,Zhang Jun,M,21,87.5;void main()printf(No.=%ldnName=%sn,stu1.no,stu1.name);print

13、f(Sex=%cnAge=%dnScore=%fn,stu1.sex,stu1.age,stu1.score); 11C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型结构体数据类型3. 3. 结构体变量结构体变量结构体变量结构体变量的初始化的初始化的初始化的初始化1. 1. 结构体类型的结构体类型的结构体类型的结构体类型的定义定义定义定义2. 2. 结构体变量的结构体变量的结构体变量的结构体变量的定义定义定义定义4. 4. 结构体变量成结构体变量成结构体变量成结构体变量成员的引用员的引用员的引用员的引用【例例7-2】静态结构体变量初始化。静态结构体变量初

14、始化。#include void main()static struct student /*定义静态结构体变量定义静态结构体变量*/long no;char name15;char sex;int age;float score;stu2=20080001,Zhang Jun,M,21,87.5;printf(No.=%ldnName=%sn,stu2.no,stu2.name);printf(Sex=%cnAge=%dnScore=%fn,stu2.sex,stu2.age,stu2.score);12C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型

15、结构体数据类型4. 4. 结构体变量结构体变量结构体变量结构体变量成员的引用成员的引用成员的引用成员的引用1. 1. 结构体类型的结构体类型的结构体类型的结构体类型的定义定义定义定义2. 2. 结构体变量的结构体变量的结构体变量的结构体变量的定义定义定义定义3. 3. 结构体变量的结构体变量的结构体变量的结构体变量的初始化初始化初始化初始化定义了结构体变量以后,就可以引用这个变量,在程序中使用结定义了结构体变量以后,就可以引用这个变量,在程序中使用结构变量时,往往不把它作为一个整体来使用。对结构变量的使用,构变量时,往往不把它作为一个整体来使用。对结构变量的使用,包括赋值、输入、输出、运算等都

16、是通过结构变量的成员来实现包括赋值、输入、输出、运算等都是通过结构变量的成员来实现的。表示结构变量成员的一般形式是:的。表示结构变量成员的一般形式是: .例如:例如:stu1.no /*学生的学号学生的学号*/stu1.name /*学生的姓名学生的姓名*/其中其中是成员运算符,它在所有的运算符中优先级最高。是成员运算符,它在所有的运算符中优先级最高。如果成员本身又是一个结构体类型,则应该用若干个如果成员本身又是一个结构体类型,则应该用若干个一级一级一级地找到最低级的成员。一级地找到最低级的成员。例如:例如:stu1.birthday.yearstu1.birthday.monthstu1.b

17、irthday.day不能将一个结构体变量作为一个整体加以引用,例如已定义了结不能将一个结构体变量作为一个整体加以引用,例如已定义了结构体变量构体变量stu1,并且进行了初始化。,并且进行了初始化。 13C语言程序设计语言程序设计 (C Programming)7.1 7.1 结构体数据类型结构体数据类型4. 4. 结构体变量结构体变量结构体变量结构体变量成员的引用成员的引用成员的引用成员的引用1. 1. 结构体类型的结构体类型的结构体类型的结构体类型的定义定义定义定义2. 2. 结构体变量的结构体变量的结构体变量的结构体变量的定义定义定义定义3. 3. 结构体变量的结构体变量的结构体变量的结

18、构体变量的初始化初始化初始化初始化【例例7-3】结构体变量的引用结构体变量的引用#include void main()struct dateint year; int month; int day;struct studentlong no; char name15;char sex; int age;struct date birthday;float score;stu2,stu1=20080001,ZhangJun,M,21,1987,3,19,87.5;stu2=stu1;stu2.age+;printf(No.=%ldnName=%sn,stu2.no,stu2.name);pri

19、ntf(Birthday=%d-%d-%dn,stu2.birthday.year,stu2.birthday.month,stu2.birthday.day);printf(Sex=%cnAge=%dnScore=%.2fn,stu2.sex,stu2.age,stu2.score); 14C语言程序设计语言程序设计 (C Programming)7.2 7.2 结构体与数组结构体与数组1. 1. 结构体数组结构体数组结构体数组结构体数组的定义的定义的定义的定义2. 2. 结构体数组的结构体数组的结构体数组的结构体数组的初始化初始化初始化初始化3. 3. 结构体数组的结构体数组的结构体数组的

20、结构体数组的引用引用引用引用结构体数组的定义方法和结构体变量的定义方法相同,可以采用结构体数组的定义方法和结构体变量的定义方法相同,可以采用三种方法定义结构体数组,本节以第二种方法为例。三种方法定义结构体数组,本节以第二种方法为例。例如:例如:struct student long no;char name15;char sex;int age;float score;char *address;stu5;定义了一个结构数组定义了一个结构数组stu,数组中包含,数组中包含5个元素,个元素,stu0stu4。每个数组元素都是一个结构体变量。每个数组元素都是一个结构体变量。 15C语言程序设计语言

21、程序设计 (C Programming)7.2 7.2 结构体与数组结构体与数组2. 2. 结构体数组结构体数组结构体数组结构体数组的初始化的初始化的初始化的初始化1. 1. 结构体数组的结构体数组的结构体数组的结构体数组的定义定义定义定义3. 3. 结构体数组的结构体数组的结构体数组的结构体数组的引用引用引用引用结构体数组可以在定义时初始化,但只能对全局的或静态存储的结构体数组可以在定义时初始化,但只能对全局的或静态存储的数组进行初始化。数组进行初始化。例如:例如:struct studentlong no;char name15;char sex;int age;float score;c

22、har *address;stu5= 20080001,Liu ping,F,20,85.0,Beijing, 20080002,Zhang bin,M,21,72.0,Anshan, 20080003,Han feng,M,21,96.5,Hefei, 20080004,zeng li,F,21,67.0,Dalian, 20080005,Wang min,F,20,57.5,Tianjin;当对全部元素作初始化赋值时,也可不给出数组长度。当对全部元素作初始化赋值时,也可不给出数组长度。 16C语言程序设计语言程序设计 (C Programming)7.2 7.2 结构体与数组结构体与数组2

23、. 2. 结构体数组结构体数组结构体数组结构体数组的引用的引用的引用的引用1. 1. 结构体数组的结构体数组的结构体数组的结构体数组的定义定义定义定义3. 3. 结构体数组的结构体数组的结构体数组的结构体数组的初始化初始化初始化初始化结构体数组的引用类似于结构体变量的引用,只是用结构体数组结构体数组的引用类似于结构体变量的引用,只是用结构体数组元素来代替结构体变量。如第一个学生的个人信息:元素来代替结构体变量。如第一个学生的个人信息:stu0.nostu0.namestu0.sexstu0.agestu0.scorestu0.address同结构体变量一样,结构体数组元素不能整体的输入输出,只

24、能同结构体变量一样,结构体数组元素不能整体的输入输出,只能以单个成员为对象进行输入输出。以单个成员为对象进行输入输出。 17C语言程序设计语言程序设计 (C Programming)7.2 7.2 结构体与数组结构体与数组2. 2. 结构体数组结构体数组结构体数组结构体数组的引用的引用的引用的引用1. 1. 结构体数组的结构体数组的结构体数组的结构体数组的定义定义定义定义3. 3. 结构体数组的结构体数组的结构体数组的结构体数组的初始化初始化初始化初始化【例例7-4】计算学生的平均成绩计算学生的平均成绩#include struct studentlong no;char name15;cha

25、r sex;int age;float score;char *address;stu5=20080001,Liu ping,F,20,85.0,Beijing,20080002,Zhang bin,M,21,72.0,Anshan,20080003,Han feng,M,21,96.5,Hefei,20080004,zeng li,F,21,67.0,Dalian,20080005,Wang min,F,20,57.5,Tianjin;18C语言程序设计语言程序设计 (C Programming)7.2 7.2 结构体与数组结构体与数组2. 2. 结构体数组结构体数组结构体数组结构体数组的引

26、用的引用的引用的引用1. 1. 结构体数组的结构体数组的结构体数组的结构体数组的定义定义定义定义3. 3. 结构体数组的结构体数组的结构体数组的结构体数组的初始化初始化初始化初始化【例例7-4】计算学生的平均成绩计算学生的平均成绩void main()int i;float ave,sum=0;for(i=0;i5;i+)sum=sum+stui.score;ave=sum/5;printf(Average=%.2fn ,ave); 19C语言程序设计语言程序设计 (C Programming)7.3 7.3 结构体与指针结构体与指针1.1.指向结构体变指向结构体变指向结构体变指向结构体变量的

27、指针量的指针量的指针量的指针2. 2. 指向结构体数指向结构体数指向结构体数指向结构体数组的指针组的指针组的指针组的指针指向一个结构体变量的指针变量称之为结构体指针变量。一个结指向一个结构体变量的指针变量称之为结构体指针变量。一个结构体变量的指针是该变量所占内存空间的首地址。通过结构体指构体变量的指针是该变量所占内存空间的首地址。通过结构体指针即可访问该结构体变量。针即可访问该结构体变量。结构体指针变量定义的一般形式为:结构体指针变量定义的一般形式为: struct 结构体名结构体名 *结构体指针变量名结构体指针变量名例如:例如:struct student long no;char name

28、15;char sex;int age;float score;char *address; stu1,stu2;struct student *pstu;结构体指针变量先赋值后才能使用。结构体指针变量先赋值后才能使用。 赋值是把结构体变量的首地赋值是把结构体变量的首地址赋予该指针变量。址赋予该指针变量。 20C语言程序设计语言程序设计 (C Programming)7.3 7.3 结构体与指针结构体与指针【例例7-5】通过结构体指针输出通过结构体指针输出程序代码:程序代码:#include struct studentlong no; char name15; char sex; int a

29、ge; float score;char *address;stu1=20080001,Liu ping,F,20,85.0,Beijing,*pstu;void main()pstu=&stu1; printf(No.=%ldnName=%sn,(*pstu).no,(*pstu).name); printf(Sex=%cnScore=%fnAddress=%snn,(*pstu).sex,(*pstu).score, (*pstu).address); printf(No.=%ldnName=%sn,pstu-no,pstu-name); printf(Sex=%cnScore=%fnAd

30、dress=%sn,pstu-sex, pstu-score, pstu-address);1.1.指向结构体变指向结构体变指向结构体变指向结构体变量的指针量的指针量的指针量的指针2. 2. 指向结构体数指向结构体数指向结构体数指向结构体数组的指针组的指针组的指针组的指针21C语言程序设计语言程序设计 (C Programming)7.3 7.3 结构体与指针结构体与指针【例例7-5】通过结构体指针输出通过结构体指针输出程序代码:程序代码:#include struct studentlong no; char name15; char sex; int age; float score;ch

31、ar *address;stu1=20080001,Liu ping,F,20,85.0,Beijing,*pstu;void main()pstu=&stu1; printf(No.=%ldnName=%sn,(*pstu).no,(*pstu).name); printf(Sex=%cnScore=%fnAddress=%snn,(*pstu).sex,(*pstu).score, (*pstu).address); printf(No.=%ldnName=%sn,pstu-no,pstu-name); printf(Sex=%cnScore=%fnAddress=%sn,pstu-sex

32、, pstu-score, pstu-address);1.1.指向结构体变指向结构体变指向结构体变指向结构体变量的指针量的指针量的指针量的指针2. 2. 指向结构体数指向结构体数指向结构体数指向结构体数组的指针组的指针组的指针组的指针22C语言程序设计语言程序设计 (C Programming)7.3 7.3 结构体与指针结构体与指针指针变量可以指向一个结构体变量,同样指针变量也可以指向一指针变量可以指向一个结构体变量,同样指针变量也可以指向一个结构体数组,此时结构体指针变量的值是整个结构数组的首地个结构体数组,此时结构体指针变量的值是整个结构数组的首地址。通过结构体指针变量的移动可以指向结

33、构体数组的任意一个址。通过结构体指针变量的移动可以指向结构体数组的任意一个元素。元素。 【例例7-6】用指针变量输出结构体数组。用指针变量输出结构体数组。#include struct studentlong no; char name15; char sex; int age; float score;char *address;stu5= 20080001,Liu ping,F,20,85.0,Beijing, 20080002,Zhang bin,M,21,72.0,Anshan, 20080003,Han feng,M,21,96.5,Hefei, 20080004,zeng li,F

34、,21,67.0,Dalian, 20080005,Wang min,F,20,57.5,Tianjin;2.2.指向结构体数指向结构体数指向结构体数指向结构体数组的指针组的指针组的指针组的指针1. 1. 指向结构体变指向结构体变指向结构体变指向结构体变量的指针量的指针量的指针量的指针23C语言程序设计语言程序设计 (C Programming)7.3 7.3 结构体与指针结构体与指针void main()struct student *pstu; clrscr(); printf(No.ttNamettSextAgetScorettAddressn); for(pstu=stu;pstuno

35、,pstu-name,pstu-sex, pstu-age,pstu-score, pstu-address); 2.2.指向结构体数指向结构体数指向结构体数指向结构体数组的指针组的指针组的指针组的指针1. 1. 指向结构体变指向结构体变指向结构体变指向结构体变量的指针量的指针量的指针量的指针24C语言程序设计语言程序设计 (C Programming)7.4 7.4 结构体与函数结构体与函数【例例7-7】输出一组学生中的最高成绩。输出一组学生中的最高成绩。#include struct studentlong no;char name15;char sex;int age;float sco

36、re;char *address; stu5=20080001,Liu ping,F,20,85.0,Beijing,20080002,Zhang bin,M,21,72.0,Anshan,20080003,Han feng,M,21,96.5,Hefei,20080004,zeng li,F,21,67.0,Dalian,20080005,Wang min,F,20,57.5,Tianjin;1. 1. 结构体指针变量结构体指针变量结构体指针变量结构体指针变量作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针2.2.结构体指针变量结构体指针变量结构体指针变量结构体指针变量作函数返回值作

37、函数返回值作函数返回值作函数返回值25C语言程序设计语言程序设计 (C Programming)7.4 7.4 结构体与函数结构体与函数void main()struct student *pstu; float max(struct student *pstu); pstu=stu;printf(Max=%.2f,max(pstu);float max(struct student *p)int i; float max;max=p-score; for(i=1;iscoremax) max= p-score; return max; 1. 1. 结构体指针变量结构体指针变量结构体指针变量结

38、构体指针变量作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针2.2.结构体指针变量结构体指针变量结构体指针变量结构体指针变量作函数返回值作函数返回值作函数返回值作函数返回值26C语言程序设计语言程序设计 (C Programming)7.4 7.4 结构体与函数结构体与函数【例例7-8】输出一组学生中的成绩最高学生的学号、姓名和成绩。输出一组学生中的成绩最高学生的学号、姓名和成绩。#include struct studentlong no;char name15;char sex;int age;float score;char *address;stu5=20080001,Liu

39、ping,F,20,85.0,Beijing,20080002,Zhang bin,M,21,72.0,Anshan,20080003,Han feng,M,21,96.5,Hefei,20080004,zeng lili,F,21,67.0,Dalian,20080005,Wang min,F,20,57.5,Tianjin;2.2.结构体指针变量结构体指针变量结构体指针变量结构体指针变量作函数返回值作函数返回值作函数返回值作函数返回值1. 1. 结构体指针变量结构体指针变量结构体指针变量结构体指针变量作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针27C语言程序设计语言程序设计 (

40、C Programming)7.4 7.4 结构体与函数结构体与函数void main()struct student *pstu,*q; struct student *max(struct student *pstu); pstu=stu; q=max(pstu); printf(No.ttNamet tScore n); printf(%ldt%st%.2fn,q-no,q-name,q-score);struct student *max(struct student *p)int i,k=0; float max;max=p-score;for(i=1;iscoremax) k=i;

41、 return p+k; 2.2.结构体指针变量结构体指针变量结构体指针变量结构体指针变量作函数返回值作函数返回值作函数返回值作函数返回值1. 1. 结构体指针变量结构体指针变量结构体指针变量结构体指针变量作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针28C语言程序设计语言程序设计 (C Programming)7.4 7.4 结构体与函数结构体与函数程序说明:程序说明:程序中定义了函数程序中定义了函数struct student *max(struct student *p),其,其形参为结构体指针变量形参为结构体指针变量p,函数的返回值也为结构体指针变量。函数的返回值也为结构体指

42、针变量。stu被定义为结构体数组,并作了初始化。被定义为结构体数组,并作了初始化。语句语句pstu=stu;把把stu的首地址赋予的首地址赋予pstu,使,使pstu指向指向stu数组。数组。以以pstu作实参进行函数调用作实参进行函数调用q=max(pstu);,并将结果返回给结构,并将结果返回给结构体指针变量体指针变量q。2.2.结构体指针变量结构体指针变量结构体指针变量结构体指针变量作函数返回值作函数返回值作函数返回值作函数返回值1. 1. 结构体指针变量结构体指针变量结构体指针变量结构体指针变量作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针作嫦娥数参数针29C语言程序设计语言程序设计 (C

43、 Programming)7.5 7.5 结构体与链表结构体与链表1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配2. 2. 链表的操作链表的操作链表的操作链表的操作在语言中不允许动态定义数组类型,也就是说数组的长度一旦在语言中不允许动态定义数组类型,也就是说数组的长度一旦定义是不可以改变的。但是在实际的应用中,有些问题的数据定义是不可以改变的。但是在实际的应用中,有些问题的数据量的大小是无法预先确定,并且在程序的运行过程中数据的个量的大小是无法预先确定,并且在程序的运行过程中数据的个数是动态改变的,为了解决此类问题,语言提供了一些内存数是动态改变的,为了解决此类问题,语言提供了一

44、些内存管理函数,这些内存管理函数可以按需要动态地增加或减少内管理函数,这些内存管理函数可以按需要动态地增加或减少内存空间。存空间。C语言中提供了语言中提供了4个有关动态存储分配的函数,即个有关动态存储分配的函数,即malloc( )、calloc( )、free( )和和realloc( )。常用的两个函数是常用的两个函数是malloc( )和和free( ):分配内存空间函数分配内存空间函数malloc()函数原形:函数原形: void *malloc(unsigned size)功能:在内存的动态存储区中分配一块长度为功能:在内存的动态存储区中分配一块长度为size字节的连续字节的连续存储

45、区。函数的返回值为该区域的首地址。存储区。函数的返回值为该区域的首地址。malloc()函数经常函数经常和和sizeof()一起使用。一起使用。 30C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配2. 2. 链表的操作链表的操作链表的操作链表的操作例如:例如: p=(int*)malloc(50);表示分配表示分配50个字节的内存空间,并强制转换为整型数据类型数组,个字节的内存空间,并强制转换为整型数据类型数组,函数的返回值为指向该整型数组的指针,把该指针赋予指针变函数的返回值为指向

46、该整型数组的指针,把该指针赋予指针变量量p。释放内存空间函数释放内存空间函数free()函数原形:函数原形: void free(void *p);功能:释放功能:释放p所指向的一块连续内存存储空间,所指向的一块连续内存存储空间,p指向被释放区域指向被释放区域的首地址。被释放区必须是由的首地址。被释放区必须是由malloc或或calloc函数所分配的区函数所分配的区域。域。 31C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配C语言中

47、动态内存管理函数的引入提高了系统内存的使用效率,语言中动态内存管理函数的引入提高了系统内存的使用效率,链表是实现动态内存分配的解决方案,它是在程序的执行过程链表是实现动态内存分配的解决方案,它是在程序的执行过程中根据需要向系统要求申请存储空间,使用结束就释放内存空中根据需要向系统要求申请存储空间,使用结束就释放内存空间,决不构成对存储区的浪费。链表是一种复杂的数据结构,间,决不构成对存储区的浪费。链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表。本节主要介绍单链表的建立、插入、删除等操作。双向链表。本

48、节主要介绍单链表的建立、插入、删除等操作。链表采用动态分配的办法为一个结构体分配内存空间,称之为一链表采用动态分配的办法为一个结构体分配内存空间,称之为一个结点。每个结点存放一个对象(学生或职工等)的数据信息。个结点。每个结点存放一个对象(学生或职工等)的数据信息。有多少个对象就应该申请分配多少个结构体内存空间,也就是有多少个对象就应该申请分配多少个结构体内存空间,也就是说要建立多少个结点,当对象增加或减少时动态的添加或释放说要建立多少个结点,当对象增加或减少时动态的添加或释放存储空间(结点)。存储空间(结点)。32C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构

49、体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配如建立一个学生学籍管理系统,有一个学生就分配一个结点,结如建立一个学生学籍管理系统,有一个学生就分配一个结点,结点之间的联系用指针来实现,如果某学生退学,可删去该结点,点之间的联系用指针来实现,如果某学生退学,可删去该结点,并释放该结点占用的存储空间。使用动态分配时,每个结点之并释放该结点占用的存储空间。使用动态分配时,每个结点之间可以是不连续的间可以是不连续的(结点内是连续的结点内是连续的)。在结点结构中定义一个。在结点结构中定义一个成员项用来存放下一结点的起始

50、地址,这个用于存放地址的成成员项用来存放下一结点的起始地址,这个用于存放地址的成员,常把它称为指针域。在第一个结点的指针域内存入第二个员,常把它称为指针域。在第一个结点的指针域内存入第二个结点的起始地址,在第二个结点的指针域内又存放第三个结点结点的起始地址,在第二个结点的指针域内又存放第三个结点的起始地址,如此串连下去直到最后一个结点。最后一个结点的起始地址,如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,可以赋值为因无后续结点连接,可以赋值为NULL。这样一种存储管理方。这样一种存储管理方式,在数据结构中称为式,在数据结构中称为“链表链表”。 33C语言程序设计语言程序设计 (C

51、 Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配图图7-1为一学生学籍管理单链表的示意图。图中每个结点是一个结为一学生学籍管理单链表的示意图。图中每个结点是一个结构体,结构体的定义如下:构体,结构体的定义如下:struct studentlong no;char name15;char sex;int age;float score;; 34C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的

52、操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配【例例7-9】建立一个建立一个10个结点的链表,存放学生数据。个结点的链表,存放学生数据。程序分析:程序分析:定义链表结点的数据结构;定义链表结点的数据结构;建立表头;建立表头;利用利用malloc函数向系统申请结点空间。函数向系统申请结点空间。对新结点赋值,将新结点的指针域赋为对新结点赋值,将新结点的指针域赋为NULL,若是空表就将新,若是空表就将新结点连接到表头,否则将新结点连接到表尾。结点连接到表头,否则将新结点连接到表尾。若有后续结点则转到(若有后续结点则转到(3),否则结束。),否则结束。程序代码:程

53、序代码:#include #include struct studentlong no;char name15;char sex;int age;float score;struct student *next;35C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配struct student *create(struct student *head,int n)struct student *p1,*p2;int i;p1=head=

54、p2=(struct student *)malloc(sizeof (struct student);printf(Input student data:);scanf(%ld,%s,%c,%d,%f,&p2-no,p2-name, &p2-sex,&p2-age,&p2-score);p2-next=NULL;for(i=1;ino,p2-name, &p2-sex,&p2-age,&p2-score);p2-next=NULL;p1-next=p2;p1=p2;return(head); 36C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链

55、表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配void print(struct student *h)struct student *t=h;while(t!=NULL)printf(n%ld,%s,%c,%d,%.2fn,t-no,t-name,t-sex,t-age,t-score);t=t-next;void main( )struct student *head;head=NULL;head=create(head,10);print(head); 37C语言程序设计语言程序设计 (C Programming)7.5

56、 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配【例例7-10】创建包含学号、姓名结点的单链表。其结点数任意个,创建包含学号、姓名结点的单链表。其结点数任意个,表以学号为序,低学号的在前,高学号的在后,以输入姓名为表以学号为序,低学号的在前,高学号的在后,以输入姓名为空作结束。在此链表中,要求删除一个给定姓名的结点,并插空作结束。在此链表中,要求删除一个给定姓名的结点,并插入一个给定学号和姓名的结点。入一个给定学号和姓名的结点。#include stdio.h#include string.h#i

57、nclude malloc. hstruct node /*结点的数据结构结点的数据结构* /int num;char name20;suct node *next; 38C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配void main( )struct node *create( ); /*函数声明函数声明*/struct node *insert( );struct node *delete( );void print( );s

58、truct node *head;char str20;int n;head=NULL; /*做空表做空表*/head=create(head); /*调用函数创建以调用函数创建以head 为头为头的链表的链表*/print(head); /*调用函数输出结点调用函数输出结点*/printf(n Please input inserted num,name:n);scanf(%d,&n); /*输入学号输入学号*/gets(str); /*输入姓输入姓名名*/head=insert(head,str,n); /*将结点插入链表将结点插入链表*/print(head);/*调用函数输出结调用函数

59、输出结点点*/printf(n Please input deleted name:n);gets(str); /*输入被输入被删姓名删姓名*/head=delete(head,str); print(head); /*调用函数输出结调用函数输出结点点*/return; 39C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配/ * * * * * * * * * 创建链表创建链表 * * * * * * * * * * /struct

60、node *create(struct node *head)struct node *p1,*p2;p1=p2=(struct node*)malloc(sizeof(struct node);printf (Please input num, name: n;);scanf(%d,&p1-num);gets(p1-name);p1-next=NULL ;while(strlen(p1-name)0)if(head=NULL) head=p1;else p2-next=p1;p2=p1;p1=(struct node *)malloc(sizeof(struct node);printf(P

61、lease input num, name: n;);scanf(%d, &p1-num);gets(p1-name);p1-next=NULL;return head; 40C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配/ * * * * * * * * * * 插入结点插入结点* * * * * * * * * * /struct node *insert(head,pstr,n)struct node *head;char *

62、pstr;int n;struct node *p1,*p2,*p3;p1=(struct node*)malloc(sizeof(struct node);strcpy(p1-name,pstr);p1-num=n;p2=head;if(head = NULL)head=p1; p1-next=NULL;elsewhile(np2-num&p2-next!=NULL)p3=p2;p2=p2-next;if(nnum)if(head =p2)head =p1;p1-next=p2; /*插入位置在表首插入位置在表首* /elsep3-next=p1;p1-next=p2; /*插入位置在表中插

63、入位置在表中* /elsep2-next=p1;p1-next=NULL ; /*插入位置在表尾插入位置在表尾* /return(head);41C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配/ * * * * * * * * * * 删除结点删除结点* * * * * * * * * /struct node *delete(head,pstr)struct node *head;char *pstr;struct node *t

64、emp,*p;temp=head ;if(head = NULL)printf(n The list is null! n);elsetemp=head ;while(strcmp(temp-name,pstr)!=0 & temp-next!=NULL)p=temp;temp=temp-next;if(strcmp(temp-name,pstr)=0)if(temp=head)head=head-next;free(temp); /*删除位置在表首删除位置在表首*/elsep-next=temp-next;printf(Delete student :%sn,temp-name);free(

65、temp); /*删除位置在表中或表尾删除位置在表中或表尾*/elseprintf(n No Found! n); /*表中没有找到要删除的数据表中没有找到要删除的数据*/return(head); 42C语言程序设计语言程序设计 (C Programming)7.5 7.5 结构体与链表结构体与链表2. 2. 链表的操作链表的操作链表的操作链表的操作1. 1. 动态存储分配动态存储分配动态存储分配动态存储分配/ * * * * * * * *链表各结点的输出链表各结点的输出* * * * * * * /void print(struct node *head)struct node *tem

66、p;temp=head;printf(nOutput students:n);while(temp!=NULL)printf(n%d-%sn, temp-num ,temp-name);temp=temp-next;return;43C语言程序设计语言程序设计 (C Programming)7.6 7.6 共用体数据类型共用体数据类型共用体又叫联合体,共用体也是将不同数据类型的数据项组成一个整体,但共用体又叫联合体,共用体也是将不同数据类型的数据项组成一个整体,但是它与结构体不同,这些不同类型的数据项在内存中所占用的起始地址是是它与结构体不同,这些不同类型的数据项在内存中所占用的起始地址是相同

67、的。相同的。共用体类型的定义形式和结构体的定义形式是相似的,向区别的就共用体类型的定义形式和结构体的定义形式是相似的,向区别的就是结构体定义的关键字是是结构体定义的关键字是 struct 而共用体定义的关键字是而共用体定义的关键字是 union。1共用体数据类型的定义共用体数据类型的定义定义一个共用体类型的一般形式为:定义一个共用体类型的一般形式为:union 共用体名共用体名类型说明符类型说明符1 成员名成员名1;类型说明符类型说明符2 成员名成员名2;. . .类型说明符类型说明符n 成员名成员名n; ;例如:例如: union mem char a;float b; 44C语言程序设计语

68、言程序设计 (C Programming)7.6 7.6 共用体数据类型共用体数据类型2共用体变量的定义共用体变量的定义共用体变量的定义和结构体变量的定义方式相同,也有三种形式。共用体变量的定义和结构体变量的定义方式相同,也有三种形式。定义一个共用体变量的一般形式为:定义一个共用体变量的一般形式为:union 共用体名共用体名类型说明符类型说明符1 成员名成员名1;类型说明符类型说明符2 成员名成员名2;. . .类型说明符类型说明符n 成员名成员名n; 变量名表列变量名表列;例如:例如:union memchar a;float b;x,y; 45C语言程序设计语言程序设计 (C Progr

69、amming)7.6 7.6 共用体数据类型共用体数据类型3共用体变量的引用,共用体变量的引用,共用体变量的应用方式和结构体变量的引用方式相同:共用体变量的应用方式和结构体变量的引用方式相同: .由于共用体变量不同时具有每个成员的值,因此,最后一个赋予它的值就是由于共用体变量不同时具有每个成员的值,因此,最后一个赋予它的值就是共用体的值。共用体的值。例如:例如:union memchar a;float b;x,y;x.a=A;x.b=100;共用体变量共用体变量x的的a成员先被赋予了成员先被赋予了A, 然后然后b成员又被赋予了成员又被赋予了100,最后共,最后共用体变量用体变量x中只存储了成

70、员中只存储了成员b的值,即的值,即100。 46C语言程序设计语言程序设计 (C Programming)7.6 7.6 共用体数据类型共用体数据类型4共用体的特点共用体的特点(1)同一内存段可放几种不同类型的成员,但每次只能存放一种数据类型的)同一内存段可放几种不同类型的成员,但每次只能存放一种数据类型的数据。例如:数据。例如:a.c=a;a.f2.1;在完成以上两个赋值运算后,只有在完成以上两个赋值运算后,只有a.f是有效的,是有效的,a.c都不再有效,例如:都不再有效,例如:printf(f,af);); /*正确的正确的*/printf(c,ac);); /*错误的错误的*/所以引用共

71、同体变量时应该特别注意当前放的是什么数据。所以引用共同体变量时应该特别注意当前放的是什么数据。(2)共用体变量地址及其各成员地址都是同一地址。即)共用体变量地址及其各成员地址都是同一地址。即&a,&ai,&ac,&af值相同。值相同。(3)不能对共用体变量名赋值。也不能定义时进行初始化。)不能对共用体变量名赋值。也不能定义时进行初始化。(4)不能把共用体变量作为函数参数,也不能使函数返回共同体变量,但可)不能把共用体变量作为函数参数,也不能使函数返回共同体变量,但可以使用指向共用体的指针。以使用指向共用体的指针。(5)允许定义共用体数组。)允许定义共用体数组。 47C语言程序设计语言程序设计

72、(C Programming)7.7 7.7 枚举类型枚举类型1枚举类型定义的一般形式为:枚举类型定义的一般形式为: enum 枚举名枚举名 枚举值表枚举值表 ;在枚举值表中应列出所有可用值。这些值也被称为枚举元素。在枚举值表中应列出所有可用值。这些值也被称为枚举元素。例如:例如:enum weekday Sunday ,Monday ,Tuesday ,Wednesday ,Thursday ,Friday ,Saturday ;枚举名为枚举名为weekday,枚举值共有,枚举值共有7个。枚举类型中个每个元素对应一个数值,个。枚举类型中个每个元素对应一个数值,系统默认从系统默认从0开始。如在

73、开始。如在weekday中,中,Sunday值为值为0,Monday值为值为1,Tuesday值为,值为,Wednesday值为,值为,Thursday值为,值为,Friday值为,值为,Saturday值为值为6。一旦定义它们的值是不能改变的。一旦定义它们的值是不能改变的。 48C语言程序设计语言程序设计 (C Programming)7.7 7.7 枚举类型枚举类型2枚举变量的说明枚举变量的说明同结构和共用体变量定义一样,枚举变量也可用不同的方式说明,即先定义同结构和共用体变量定义一样,枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。后说明,同时定义说明或直接说明。例

74、如:例如:enum weekdaySunday,Monday,Tuesday,Wednesday ,Thursday,Friday,Saturday;enum weekday a,b;或者为:或者为:enum weekdaySunday,Monday,Tuesday,Wednesday,Thursday ,Friday ,Saturday a,b;或者为:或者为:enum Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturdaya,b; 49C语言程序设计语言程序设计 (C Programming)7.8 7.8 类型定义符类型定义符Ty

75、pedefTypedef整型、字符型、实型等数据类型是系统定义的类型说明符,整型、字符型、实型等数据类型是系统定义的类型说明符,C语言还允许用语言还允许用户自定义类型说明符,也就是说为已有的数据类型取个户自定义类型说明符,也就是说为已有的数据类型取个“别名别名”。类型定。类型定义符义符typedef即可用来完成此功能。即可用来完成此功能。typedef定义的一般形式为:定义的一般形式为:typedef 原类型名原类型名 新类型名新类型名 1简单的类型名称定义简单的类型名称定义例如:例如:typedef float REAL;一旦定义,则一旦定义,则float 和和REAL两者是等价的,就可用两

76、者是等价的,就可用INTEGER来代替来代替int作整作整型变量的说明了。型变量的说明了。 例如:例如: REAL a,b;它等价于:它等价于: float a,b; 50C语言程序设计语言程序设计 (C Programming)7.8 7.8 类型定义符类型定义符TypedefTypedef2结构体类型名称定义结构体类型名称定义例如:例如:typedef struct studentlong no;char name15; int age; STU;定义的定义的STU等同于等同于student的结构体类型,然后结构体变量的定义就可以是:的结构体类型,然后结构体变量的定义就可以是:STU st

77、u1,stu2;它等价于:它等价于:struct student stu1,stu2;51C语言程序设计语言程序设计 (C Programming)7.8 7.8 类型定义符类型定义符TypedefTypedef3数组类型定义数组类型定义例如:例如: typedef char ADDRESS20; 表示表示ADDRESS是字符数组类型,数组长度为是字符数组类型,数组长度为20。然后可用。然后可用ADDRESS 进行进行数组说明,如:数组说明,如: ADDRESS str1,str2;它等价于:它等价于: char str120,str220习惯上常把用习惯上常把用typedef定义的类型名称用

78、大写字母来表示,以区别于系统定义定义的类型名称用大写字母来表示,以区别于系统定义的标识符。的标识符。需要注意的是需要注意的是typedef可以重新定义各种类型名,但不能定义变量;可以重新定义各种类型名,但不能定义变量;typedef与与define有相似之处,但有相似之处,但define是由编译预处理完成的,是由编译预处理完成的,typedef是是在编译时完成的,因此更为灵活方便。使用在编译时完成的,因此更为灵活方便。使用typedef有利于提高程序的通有利于提高程序的通用性、移植性和可读性。用性、移植性和可读性。 52C语言程序设计语言程序设计 (C Programming)C C C C语

79、言程序设计语言程序设计语言程序设计语言程序设计 (C Programming)(C Programming)(C Programming)(C Programming)辽宁科技大学53C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define #define 8.2 8.2 文件包含文件包含#include#include54C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define#define1. 1. 不带参有宏定义不带参有宏定义不带参有宏定义不带参有宏定义2. 2. 带参的宏定义带参的宏定义带参的宏定义

80、带参的宏定义定义的一般形式为:定义的一般形式为:#define 标示符标示符 字符串字符串其中的其中的“#”表示这是一条预处理命令。表示这是一条预处理命令。“define”为定义宏命令。为定义宏命令。“标示符标示符”为所定义的宏名。为所定义的宏名。“字符串字符串”可以是常数、表达式、可以是常数、表达式、格式串等。如格式串等。如:#define PI 3.1415926#define PR printf(“*”) 无参宏的使用可以减少程序输入量无参宏的使用可以减少程序输入量, 方便程序的调试与修改。方便程序的调试与修改。 55C语言程序设计语言程序设计 (C Programming)8.1 8.

81、1 宏定义宏定义#define#define1. 1. 不带参有宏定义不带参有宏定义不带参有宏定义不带参有宏定义2. 2. 带参的宏定义带参的宏定义带参的宏定义带参的宏定义【例例8-1】 求求N个数的平均值,并输出其最大值与最小值。个数的平均值,并输出其最大值与最小值。程序代码:程序代码:#define N 100 #include void main() float aN,s,ver,max,min;int k; for(k=0;kN;k+) scanf(“%f”,&ak); s=max=min=a0; for(k=1;kmax) max=ak; if(akmin) min=ak; s+=a

82、k; ver=s/N; printf(“n%f,%f,%f”,ver,max,min); 56C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define#define1. 1. 不带参有宏定义不带参有宏定义不带参有宏定义不带参有宏定义2. 2. 带参的宏定义带参的宏定义带参的宏定义带参的宏定义【例例8-2】宏替换的应用。宏替换的应用。程序代码:程序代码:#define Q (x*x*x+2*x*x+1) #include void main() long x,y; scanf(“%d”,&x); y=Q*Q+(x-1)*(Q-1)+Q; printf(

83、“ny=%ld”,y); 57C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define#define1. 1. 不带参有宏定义不带参有宏定义不带参有宏定义不带参有宏定义2. 2. 带参的宏定义带参的宏定义带参的宏定义带参的宏定义不带参数的宏定义应该注意的一些问题不带参数的宏定义应该注意的一些问题(1) 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符、取代宏名,这只是一种简单的代换,字符串中可以含任何字符、常数或表达式,常数或表达式,【例

84、例8-3】中的字符串就是一个表达式,预处理程中的字符串就是一个表达式,预处理程序对字符串不作任何检查。因此,这个字符串的正确与否程序员序对字符串不作任何检查。因此,这个字符串的正确与否程序员要注意把握。要注意把握。(2) 宏定义不是说明或语句,在行末不必加分号,如果不小心加上宏定义不是说明或语句,在行末不必加分号,如果不小心加上一个一个“;”,那么这个,那么这个“;”将一同参加替换。读者可以将将一同参加替换。读者可以将【例例8-2】的宏定义语句加上的宏定义语句加上“;”,编译时将报错,编译无法通过。,编译时将报错,编译无法通过。(3) 习惯上宏名都用大写字母来表示。一般来说,宏名用大写字母习惯

85、上宏名都用大写字母来表示。一般来说,宏名用大写字母表示,以便于与变量区别,但这并不意味着宏名不能用小写字母,表示,以便于与变量区别,但这并不意味着宏名不能用小写字母,只是为了与变量区别而已。只是为了与变量区别而已。(4) 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束,若不希望宏定义命令到源程序结束时终止,可以在需要终结束,若不希望宏定义命令到源程序结束时终止,可以在需要终止其作用域的地方用止其作用域的地方用#undef命令。命令。(5) 如果宏名在程序中被引号括起来,则不进行宏替换,下面就是如果宏名在程序中被引号括起来,则不进

86、行宏替换,下面就是这样一个例子。这样一个例子。58C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define#define2. 2. 带参有宏定义带参有宏定义带参有宏定义带参有宏定义1.1.不带参的宏定义不带参的宏定义不带参的宏定义不带参的宏定义带参宏定义的一般形式为:带参宏定义的一般形式为:#define 宏名(形参表)字符串宏名(形参表)字符串在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅宏要展开,而且要用实参去数。对带参数的宏,在调用中,不仅宏要展开

87、,而且要用实参去替换形参。替换形参。带参宏调用的一般形式为:带参宏调用的一般形式为:宏名(实参表);宏名(实参表);例如例如:#define Q(x,y) x*x*y+2*x*y+y / *宏定义宏定义 */ a=Q(3,5); / *宏调用宏调用 */在宏调用时,用实参去代替形参在宏调用时,用实参去代替形参x,经预处理宏展开后语句为:,经预处理宏展开后语句为:a=3*3*5+2*3*5+5;带形参的宏,具有较强的功能,但也有很多地方需要读者注意,带形参的宏,具有较强的功能,但也有很多地方需要读者注意,稍不小心,可能就会出错。下面结合读者容易忽略的地方通过应稍不小心,可能就会出错。下面结合读者

88、容易忽略的地方通过应用实例介绍带形参的宏定义的正确应用。用实例介绍带形参的宏定义的正确应用。 59C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define#define2. 2. 带参有宏定义带参有宏定义带参有宏定义带参有宏定义1.1.不带参的宏定义不带参的宏定义不带参的宏定义不带参的宏定义【例例8-3】利用带参数的宏实现简单函数的功能。利用带参数的宏实现简单函数的功能。程序代码:程序代码:#define MAX(x,y) (xy) ? x:y /* 带参宏定义,实现求两个数带参宏定义,实现求两个数中较大的中较大的 */ #include void

89、main() int a,b,max; scanf(“%d,%d” ,&a,&b); max=MAX(a,b); printf(“max=%dn” ,max); 60C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define#define2. 2. 带参有宏定义带参有宏定义带参有宏定义带参有宏定义1.1.不带参的宏定义不带参的宏定义不带参的宏定义不带参的宏定义在这个例子中,要注意如下问题:在这个例子中,要注意如下问题:(1)带参宏定义中,宏名和形参表之间不能随便加入空格;否则)带参宏定义中,宏名和形参表之间不能随便加入空格;否则将空格以后的字符都作为替

90、代字符串的一部分。将空格以后的字符都作为替代字符串的一部分。例如把上例中的宏定义:例如把上例中的宏定义:#define MAX(x,y)(xy)?x:y写成:写成:#define MAX (x,y)(xy)?x:y将被认为是无参宏定义,宏名定义将被认为是无参宏定义,宏名定义MAX代表字符串代表字符串(x,y)(xy)?x:y 。宏展开时,宏调用语句。宏展开时,宏调用语句: max=MAX(a,b););将变为:将变为: max=(x,y)(xy)?x:y(a,b);这显然是错误的。实际上,在上例中的宏定义语句中插入空格后,这显然是错误的。实际上,在上例中的宏定义语句中插入空格后,编译将失败。编

91、译将失败。61C语言程序设计语言程序设计 (C Programming)8.1 8.1 宏定义宏定义#define#define2. 2. 带参有宏定义带参有宏定义带参有宏定义带参有宏定义1.1.不带参的宏定义不带参的宏定义不带参的宏定义不带参的宏定义(2)在带参宏定义中,形式参数不分配内存单元,因此不必作类)在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值,要用它们去代换行参,型定义。而宏调用中的实参有具体的值,要用它们去代换行参,因此必须作类型说明。读者要注意这与函数的区别。在函数原型因此必须作类型说明。读者要注意这与函数的区别。在函数原型的定义中,要

92、定义形参的数据类型,而且函数调用过程中形参和的定义中,要定义形参的数据类型,而且函数调用过程中形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行予形参,进行“值传递值传递”,而在带参宏中,只是符号代换,不存,而在带参宏中,只是符号代换,不存在值传递的问题。在值传递的问题。(3) 在宏定义中,括号的使用要注意,不同位置的括号,往往效果在宏定义中,括号的使用要注意,不同位置的括号,往往效果不一样,下面举例说明宏定义中括号的作用。不一样,下面举例说明宏定义中括号的作用。62C语言程序设计语言程序设计 (C Program

93、ming)8.1 8.1 宏定义宏定义#define#define2. 2. 带参有宏定义带参有宏定义带参有宏定义带参有宏定义1.1.不带参的宏定义不带参的宏定义不带参的宏定义不带参的宏定义【例例8-4】宏定义中括号的使用问题举例。宏定义中括号的使用问题举例。程序代码:程序代码:#define QA(x,y) x*y#define QB(x,y) (x)*(y)#include void main() int a=3,b=4,m,n; m=QA(a+1,b+2); n=QB(a+1,b+2); printf(“m=%dn n=%d”,m,n); 63C语言程序设计语言程序设计 (C Progr

94、amming)8.1 8.1 宏定义宏定义#define#define2. 2. 带参有宏定义带参有宏定义带参有宏定义带参有宏定义1.1.不带参的宏定义不带参的宏定义不带参的宏定义不带参的宏定义(4) 宏展开与函数的调用是不同的。宏展开与函数的调用是不同的。函数调用时要把实参表达式的值求出来再传递给形参,而宏代换函数调用时要把实参表达式的值求出来再传递给形参,而宏代换中对实参表达式不作计算(当作字符串)直接地照原样代换。中对实参表达式不作计算(当作字符串)直接地照原样代换。函数调用是在程序运行时处理的函数调用是在程序运行时处理的,分配临时的内存单元分配临时的内存单元.而宏展开则而宏展开则是在编

95、译时进行的是在编译时进行的,在展开时并不分配内存单元在展开时并不分配内存单元,不进行值的传递处不进行值的传递处理理,也没有也没有” 返回值返回值”的概念。的概念。函数中的实参和形参都要定义类型,二者的类型要求一致函数中的实参和形参都要定义类型,二者的类型要求一致,而宏不而宏不存在类型问题,宏名无类型,它的参数也无类型。存在类型问题,宏名无类型,它的参数也无类型。64C语言程序设计语言程序设计 (C Programming)8.2 8.2 文件包含文件包含includeinclude所谓所谓“文件包含文件包含”处理是指一个源文件可以将另外一个源文件的全部内容包处理是指一个源文件可以将另外一个源文

96、件的全部内容包含进来含进来,即将另外的文件包含到本文件之中。即将另外的文件包含到本文件之中。C语言提供了语言提供了#include命令用来命令用来实现实现“文件包含文件包含”的操作。一般形式为的操作。一般形式为:#include “文件名文件名” 或或 #include 在程序设计中,文件包含是很有用的。有些公用的符号常量或宏定义等可单在程序设计中,文件包含是很有用的。有些公用的符号常量或宏定义等可单独组成一个文件,在其他文件的开头用包含命令包含该文件即可使用。这样,独组成一个文件,在其他文件的开头用包含命令包含该文件即可使用。这样,可避免在每个文件开头都去书写那些公用量,这样可以节省时间、减

97、少出错。可避免在每个文件开头都去书写那些公用量,这样可以节省时间、减少出错。对于对于C系统提供的标准库函数,也可以通过文件包含使之包含到当前的程序里,系统提供的标准库函数,也可以通过文件包含使之包含到当前的程序里,从而实现库函数的调用。例如在前面章节中已经用到的文件包含处理:从而实现库函数的调用。例如在前面章节中已经用到的文件包含处理: 65C语言程序设计语言程序设计 (C Programming)8.2 8.2 文件包含文件包含includeinclude对文件包含命令还要说明以下几点:对文件包含命令还要说明以下几点:(1)包含命令中的文件名可以用双引号括起来,也可以用尖括号括起来。例)包含

98、命令中的文件名可以用双引号括起来,也可以用尖括号括起来。例如以下写法都是允许的:如以下写法都是允许的:#include “stdio.h”#include 但是这两种写法在文件的路径搜索的顺序上有区别的:使用尖括号但是这两种写法在文件的路径搜索的顺序上有区别的:使用尖括号()表示表示在包含文件路径中去查找(包含路径是由用户在设置环境时设置的),而不在包含文件路径中去查找(包含路径是由用户在设置环境时设置的),而不在源文件路径去查找,如果没有找到指定的文件,就到包含路径中去查找。在源文件路径去查找,如果没有找到指定的文件,就到包含路径中去查找。用户编程时可以根据自己文件所在的路径来选择某一种命令

99、形式。用户编程时可以根据自己文件所在的路径来选择某一种命令形式。(2)文件包含命令每行写一条,只能写一个文件名,结尾不加)文件包含命令每行写一条,只能写一个文件名,结尾不加“;”。被包。被包含的文件必须是源文件而不能是目标文件。文件名可以任意,但通常以含的文件必须是源文件而不能是目标文件。文件名可以任意,但通常以“h”作为后缀,被包含文件通常放在包含文件的头部,因此被包含文件常被称为作为后缀,被包含文件通常放在包含文件的头部,因此被包含文件常被称为“头文件头文件”。(3)一个)一个#include命令只能指定一个被包含文件,若有多个文件要包含,则命令只能指定一个被包含文件,若有多个文件要包含,

100、则需用多个需用多个#include命令。命令。66C语言程序设计语言程序设计 (C Programming)8.2 8.2 文件包含文件包含includeinclude(4) 如果文件如果文件file1包含文件包含文件file2,而在文件,而在文件file2中又要包含文件中又要包含文件file3的内容,的内容,则可在文件则可在文件file1用两个用两个#include命令分别包含文件命令分别包含文件file2和文件和文件file3,而且文,而且文件件file3要出现在文件要出现在文件file2之前,即在文件中定义:之前,即在文件中定义:#include #include 这样这样file1和和

101、file2都可以用都可以用file3的内容。的内容。(5) 在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。套的。(6) 被包含文件被包含文件(如如)与其所在文件(如),经编译预处理后已成为同一文件,与其所在文件(如),经编译预处理后已成为同一文件,因此,如果中有全局静态变量,它在文件中有效,不必用因此,如果中有全局静态变量,它在文件中有效,不必用extern声明。声明。 67C语言程序设计语言程序设计 (C Programming)C C C C语言程序设计语言程序设计语言程序设计语言程序设计 (C Pro

102、gramming)(C Programming)(C Programming)(C Programming)辽宁科技大学68C语言程序设计语言程序设计 (C Programming)1 1、文件的概念,文件的打开、关闭。、文件的概念,文件的打开、关闭。2 2、文件的读写函数及使用方法、文件的读写函数及使用方法本章学习目标本章学习目标本章学习目标本章学习目标69C语言程序设计语言程序设计 (C Programming)9.1 C9.1 C文件概述文件概述9.2 9.2 文件的打开与关闭文件的打开与关闭9.3 9.3 文件的读写文件的读写9.4 9.4 文件定位函数文件定位函数 9.5 9.5 文

103、件出错检测函数文件出错检测函数70C语言程序设计语言程序设计 (C Programming)9.1 C9.1 C文件概述文件概述计算机术语中的计算机术语中的“文件文件”的含义比较广,泛指存储在外部介质上的含义比较广,泛指存储在外部介质上数据的集合。从不同的角度可对文件作不同的分类。数据的集合。从不同的角度可对文件作不同的分类。普通文件和设备文件普通文件和设备文件按用户的角度可将文件分为普通文件和设备文件两种。按用户的角度可将文件分为普通文件和设备文件两种。普通文件又可分为程序文件和数据文件。前面各章我们多次使用普通文件又可分为程序文件和数据文件。前面各章我们多次使用的源文件、目标文件、可执行程

104、序等被称作程序文件,程序中的源文件、目标文件、可执行程序等被称作程序文件,程序中所需输入的数据和程序运行输出的数据构成的文件被称作数据所需输入的数据和程序运行输出的数据构成的文件被称作数据文件。本章所介绍的文件是指数据文件。文件。本章所介绍的文件是指数据文件。设备文件是指与主机相联的一切能进行输入和输出的终端设备,设备文件是指与主机相联的一切能进行输入和输出的终端设备,如显示器、打印机、键盘等。在操作系统中,把外部设备也看如显示器、打印机、键盘等。在操作系统中,把外部设备也看作是一个文件来进行管理,把它们的输入、输出等同于对磁盘作是一个文件来进行管理,把它们的输入、输出等同于对磁盘文件的读和写

105、。通常键盘被定义为标准输入文件,显示器被定文件的读和写。通常键盘被定义为标准输入文件,显示器被定义为标准输出文件。前面经常使用的义为标准输出文件。前面经常使用的scanf、getchar函数,函数,printf、putchar函数就属于这类输入输出。函数就属于这类输入输出。 1.C1.C文件的分类文件的分类文件的分类文件的分类2. 2. 文件脂针文件脂针文件脂针文件脂针71C语言程序设计语言程序设计 (C Programming)9.1 C9.1 C文件概述文件概述ASCII码文件和二进制码文件码文件和二进制码文件在在C语言中,文件可以看作字节的序列,按文件内数据的组织形语言中,文件可以看作字

106、节的序列,按文件内数据的组织形式可将文件分为式可将文件分为ASCII码文件和二进制码文件两种。码文件和二进制码文件两种。ASCII码文件也称为文本文件,这种文件在磁盘中存放时每个字码文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放字符对应的符对应一个字节,用于存放字符对应的ASCII码。二进制文件码。二进制文件是按二进制的编码方式来存放文件的,它把内存中的数据按其是按二进制的编码方式来存放文件的,它把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。在内存中的存储形式原样输出到磁盘上存放。例如例如1234为普通的整型数据,若将其存入为普通的整型数据,若将其存入AS

107、CII码文件中,则是码文件中,则是分别以分别以 1, 2, 3,4这四个字符的这四个字符的ASCII码值存入文件的,因此它占码值存入文件的,因此它占4个字节。个字节。 1.C1.C文件的分类文件的分类文件的分类文件的分类2. 2. 文件脂针文件脂针文件脂针文件脂针72C语言程序设计语言程序设计 (C Programming)9.1 C9.1 C文件概述文件概述ASCII码文件的存储形式码文件的存储形式 1.C1.C文件的分类文件的分类文件的分类文件的分类2. 2. 文件脂针文件脂针文件脂针文件脂针字符字符1234ASCII码码49505152存存储储形式形式0011 00010011 0010

108、0011 00110011 0100二进制文件的存储形式二进制文件的存储形式 原十原十进进制数制数值值1234转换为转换为二二进进制数制数值值10011010010二二进进制文件的存制文件的存储储形式形式73C语言程序设计语言程序设计 (C Programming)9.1 C9.1 C文件概述文件概述缓冲文件系统和非缓冲文件缓冲文件系统和非缓冲文件C的文件系统可分为缓冲文件系统和非缓冲文件系统两类。的文件系统可分为缓冲文件系统和非缓冲文件系统两类。缓冲文件系统:系统自动地在内存区为每一个正在使用的文件开缓冲文件系统:系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区。用缓冲文件系统进行的输

109、入输出又称为高级磁辟一个缓冲区。用缓冲文件系统进行的输入输出又称为高级磁盘输入输出。盘输入输出。非缓冲文件系统:系统不自动开辟确定大小的缓冲区,而由程序非缓冲文件系统:系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。用非缓冲文件系统进行的输入输出又为每个文件设定缓冲区。用非缓冲文件系统进行的输入输出又称为低级输入输出系统。称为低级输入输出系统。前者功能十分强大,为用户提供了很多方便,后者则直接依赖于前者功能十分强大,为用户提供了很多方便,后者则直接依赖于操作系统。缓冲文件系统输入输出称为标准输入输出(标准操作系统。缓冲文件系统输入输出称为标准输入输出(标准I/O),非缓冲文件系统

110、输入输出称为系统输入输出(系统),非缓冲文件系统输入输出称为系统输入输出(系统I/O)。非缓冲文件系统只以二进制方式处理文件,使程序的)。非缓冲文件系统只以二进制方式处理文件,使程序的可移植性降低,因此可移植性降低,因此ANSI C标准采用缓冲文件系统。标准采用缓冲文件系统。 1.C1.C文件的分类文件的分类文件的分类文件的分类2. 2. 文件脂针文件脂针文件脂针文件脂针74C语言程序设计语言程序设计 (C Programming)9.1 C9.1 C文件概述文件概述在缓冲文件系统中,每个被使用的文件都在内存开辟一个区域,在缓冲文件系统中,每个被使用的文件都在内存开辟一个区域,用来存放文件的相

111、关信息(如文件名、文件状态和文件当前位用来存放文件的相关信息(如文件名、文件状态和文件当前位置等)。这些信息保存在一个结构体变量中。该结构体类型是置等)。这些信息保存在一个结构体变量中。该结构体类型是系统定义的,系统为其取名为系统定义的,系统为其取名为FILE。Turbo C在在stdio.h文件中有以下的文件类型声明文件中有以下的文件类型声明:typedef struct short level; /*缓冲区缓冲区满满或或空空的程度的程度*/unsigned flags; /*文件状态标志文件状态标志*/char fd; /*文件描述符文件描述符*/unsigned char hold; /

112、*如无缓冲区不读取字符如无缓冲区不读取字符*/short bsize; /*级冲区的大小级冲区的大小*/unsigned char *baffer; /*数据缓冲区的位置数据缓冲区的位置*/unsigned ar *curp; /*指针,当前的指向指针,当前的指向*/unsigned istemp; /*临时文件,指示器临时文件,指示器*/short token; /*用于有效性检查用于有效性检查*/ FILE;2.2.文件指针文件指针文件指针文件指针1.C1.C文件的分类文件的分类文件的分类文件的分类75C语言程序设计语言程序设计 (C Programming)9.1 C9.1 C文件概述文

113、件概述语言中用一个指针变量指向一个文件,这个指针称为文件指针。语言中用一个指针变量指向一个文件,这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作。通过文件指针就可对它所指的文件进行各种操作。定义说明文件指针的一般形式为:定义说明文件指针的一般形式为: FILE *指针变量标识符;指针变量标识符;例如:例如:FILE *fp;/*fp 是一个指向是一个指向FILE类型结构体的指针变量类型结构体的指针变量*/表示表示fp是指向是指向FILE类型结构体的指针变量,通过类型结构体的指针变量,通过fp即可找存放某即可找存放某个文件信息的结构体变量,然后按结构体变量提供的信息找到个文件信息

114、的结构体变量,然后按结构体变量提供的信息找到该文件,实施对文件的操作。有几个文件就可以设几个该文件,实施对文件的操作。有几个文件就可以设几个FILE类型的指针变量。习惯上把类型的指针变量。习惯上把fp称为指向一个文件的指针。称为指向一个文件的指针。 2.2.文件指针文件指针文件指针文件指针1.C1.C文件的分类文件的分类文件的分类文件的分类76C语言程序设计语言程序设计 (C Programming)9.2 9.2 文件的打开与关闭文件的打开与关闭文文件件在在进进行行读读写写操操作作之之前前要要先先打打开开,使使用用完完毕毕要要关关闭闭。打打开开文文件件,就就是是建建立立文文件件的的各各种种相

115、相关关信信息息,并并使使文文件件指指针针指指向向该该文文件件,可可以以对对文文件件进进行行操操作作。关关闭闭文文件件则则是是断断开开指指针针与与文文件件之之间间的的联联系系,禁止再对该文件进行操作。禁止再对该文件进行操作。C语言用语言用fopen函数实现打开一个文件,其调用的一般形式为:函数实现打开一个文件,其调用的一般形式为:文件指针名文件指针名=fopen(文件名文件名,使用文件方式使用文件方式);其中:其中:“文件指针名文件指针名”必须是被说明为必须是被说明为FILE 类型的指针变量;类型的指针变量;“文件名文件名”是被打开文件的文件名,是字符串常量或字符串数组;是被打开文件的文件名,是

116、字符串常量或字符串数组;“使用文件方式使用文件方式”是指文件的类型和使用方式。是指文件的类型和使用方式。1.1.文件的打开文件的打开文件的打开文件的打开2.2.文件的关闭文件的关闭文件的关闭文件的关闭77C语言程序设计语言程序设计 (C Programming)9.2 9.2 文件的打开与关闭文件的打开与关闭例如:例如:FILE *fp; /*定义定义fp为文件指针变量为文件指针变量*/fp= fopen(file1,r); /*以只读方式打开以只读方式打开file1*/表示在当前目录下打开文件表示在当前目录下打开文件file1,只允许进行,只允许进行“读读”操作,操作,fopen函数返回指向

117、函数返回指向file1文件的指针并赋给文件的指针并赋给fp,这样,这样fp就和文就和文件件file1相联系了,或者说,相联系了,或者说,fp指向指向file1文件。可以看出,在打文件。可以看出,在打开一个文件时,通知给编译系统以下开一个文件时,通知给编译系统以下3个信息:个信息:需要打开的文件名,也就是准备访问的文件的名字;需要打开的文件名,也就是准备访问的文件的名字;使用文件的方式使用文件的方式(读读还是还是写写等等);让哪一个指针变量指向被打开的文件。让哪一个指针变量指向被打开的文件。 1.1.文件的打开文件的打开文件的打开文件的打开2.2.文件的关闭文件的关闭文件的关闭文件的关闭78C语

118、言程序设计语言程序设计 (C Programming)9.2 9.2 文件的打开与关闭文件的打开与关闭文件的文件的12种使用方式种使用方式 1.1.文件的打开文件的打开文件的打开文件的打开2.2.文件的关闭文件的关闭文件的关闭文件的关闭文件文件类类型型使用方式使用方式 意意义义备备注注ASCII码码文件文件“r”只只读读:打开一个文本文件,只允:打开一个文本文件,只允许读许读数据数据旧文件旧文件“w”只写:打开或建立一个文本文件,只允只写:打开或建立一个文本文件,只允许许写数据写数据新文件新文件“a”追加:打开一个文本文件,并在文件末尾写数据追加:打开一个文本文件,并在文件末尾写数据旧文件旧文

119、件“r+”读读写:打开一个文本文件,允写:打开一个文本文件,允许读许读和写和写旧文件旧文件“w+”读读写:打开或建立一个文本文件,允写:打开或建立一个文本文件,允许读许读写写新文件新文件“a+”读读写:打开一个文本文件,允写:打开一个文本文件,允许读许读,或在文件末追加数据,或在文件末追加数据旧文件旧文件二二进进制制文件文件“rb”只只读读:打开一个二:打开一个二进进制文件,只允制文件,只允许读许读数据数据旧文件旧文件“wb”只写:打开或建立一个二只写:打开或建立一个二进进制文件,只允制文件,只允许许写数据写数据新文件新文件“ab”追加:打开一个二追加:打开一个二进进制文件,并在文件末尾写数据

120、制文件,并在文件末尾写数据旧文件旧文件“rb+”读读写:打开一个二写:打开一个二进进制文件,允制文件,允许读许读和写和写旧文件旧文件“wb+”读读写:打开或建立一个二写:打开或建立一个二进进制文件,允制文件,允许读许读和写和写新文件新文件“ab+”读读写:打开一个二写:打开一个二进进制文件,允制文件,允许读许读,或在文件末追加数据,或在文件末追加数据旧文件旧文件79C语言程序设计语言程序设计 (C Programming)9.2 9.2 文件的打开与关闭文件的打开与关闭对于文件的使用方式有以下几点说明:对于文件的使用方式有以下几点说明: 用用r方式打开的文件只能用于向计算机输入而不能用作向该方

121、式打开的文件只能用于向计算机输入而不能用作向该文件输出数据,而且该文件应该已经存在,不能用文件输出数据,而且该文件应该已经存在,不能用r方式打方式打开一个并不存在的文件开一个并不存在的文件(即输入文件即输入文件),否则出错。,否则出错。 用用w方式打开的文件只能用于向该文件写数据方式打开的文件只能用于向该文件写数据(即输出文件即输出文件),而不能用来向计算机输入。如果原来不存在该文件,则在打,而不能用来向计算机输入。如果原来不存在该文件,则在打开时新建立一个以指定的名字命名的文件。如果原来已存在一开时新建立一个以指定的名字命名的文件。如果原来已存在一个以该文件名命名的文件,则在打开时将该文件删

122、去,然后重个以该文件名命名的文件,则在打开时将该文件删去,然后重新建立一个新文件。新建立一个新文件。 如果希望向文件末尾添加新的数据如果希望向文件末尾添加新的数据(不希望删除原有数据不希望删除原有数据),则,则应该用应该用a方式打开。但此时该文件必须已存在,否则将得到方式打开。但此时该文件必须已存在,否则将得到出错信息。打开时,位置指针移到文件末尾。出错信息。打开时,位置指针移到文件末尾。 用用r+、w+、a+方式打开的文件既可以用来输入数据,也方式打开的文件既可以用来输入数据,也可以用来输出数据。用可以用来输出数据。用r+方式时该文件应该已经存在,以便方式时该文件应该已经存在,以便能向计算机

123、输入数据。用能向计算机输入数据。用w+方式则新建立一个文件,先向方式则新建立一个文件,先向此文件写数据,然后可以读此文件中的数据。用此文件写数据,然后可以读此文件中的数据。用a+方式打开方式打开的文件,原来的文件不被删去,位置指针移到文件末尾,可以的文件,原来的文件不被删去,位置指针移到文件末尾,可以添加,也可以读。添加,也可以读。1.1.文件的打开文件的打开文件的打开文件的打开2.2.文件的关闭文件的关闭文件的关闭文件的关闭80C语言程序设计语言程序设计 (C Programming)9.2 9.2 文件的打开与关闭文件的打开与关闭 如果不能实现如果不能实现打开打开的任务,的任务,fopen

124、函数将会带回一个出错信函数将会带回一个出错信息。出错的原因可能是用息。出错的原因可能是用r方式打开一个并不存在的文件方式打开一个并不存在的文件;磁磁盘出故障盘出故障;磁盘己满无法建立新文件等。此时磁盘己满无法建立新文件等。此时fopen函数将带回函数将带回一个空指针值一个空指针值NULL(NULL在在stdio.h文件中已被定义为文件中已被定义为0)。一般地,使用一般地,使用fopen函数打开一个文件时,要检查文件打开的正函数打开一个文件时,要检查文件打开的正确性,以便确定程序能否继续执行下去。例如:确性,以便确定程序能否继续执行下去。例如:if(fp=fopen(file1,r)=NULL)

125、 printf(This not opened! ); exit(0); 其中其中exit()函数是停止程序的执行,使控制返回操作系统。函数是停止程序的执行,使控制返回操作系统。 用以上方式可以打开文本文件或二进制文件,这是用以上方式可以打开文本文件或二进制文件,这是ANSI C的的规定,用同一种缓冲文件系统来处理文本文件和二进制文件。规定,用同一种缓冲文件系统来处理文本文件和二进制文件。但目前使用的有些但目前使用的有些C编译系统可能不完全提供所有这些功能编译系统可能不完全提供所有这些功能(例例如有的只能用如有的只能用r、w、a方式方式),有的,有的C版本不用版本不用r+、w+、a+,而用,而

126、用rw、wr、ar等,请读者注意所用系等,请读者注意所用系统的规定。统的规定。 在向计算机输入文本文件时,将回车换行符转换为一个换行符,在向计算机输入文本文件时,将回车换行符转换为一个换行符,在输出时把换行符转换成为回车和换行两个字符。在用二进制在输出时把换行符转换成为回车和换行两个字符。在用二进制文件时,不进行这种转换,在内存中的数据形式与输出到外部文件时,不进行这种转换,在内存中的数据形式与输出到外部文件中的数据形式完全一致,一一对应。文件中的数据形式完全一致,一一对应。 在程序开始运行时,系统自动打开在程序开始运行时,系统自动打开3个标准文件个标准文件:标准输入、标标准输入、标准输出、标

127、准出错输出。准输出、标准出错输出。 1.1.文件的打开文件的打开文件的打开文件的打开2.2.文件的关闭文件的关闭文件的关闭文件的关闭81C语言程序设计语言程序设计 (C Programming)9.2 9.2 文件的打开与关闭文件的打开与关闭文件一旦使用完毕,应用关闭文件函数把文件关闭,以避免文件文件一旦使用完毕,应用关闭文件函数把文件关闭,以避免文件的数据丢失等错误。关闭就是使文件指针变量不指向该文件,的数据丢失等错误。关闭就是使文件指针变量不指向该文件,也就是文件指针变量与文件的联系断开,此后不能通过该指针也就是文件指针变量与文件的联系断开,此后不能通过该指针对原来与其相联系的文件进行读写

128、操作。对原来与其相联系的文件进行读写操作。C语言用语言用fclose函数实现关闭一个文件,其调用的一般形式为:函数实现关闭一个文件,其调用的一般形式为:fclose(文件指针文件指针);例如:例如:fclose(fp);正常完成关闭文件操作时,正常完成关闭文件操作时,fclose函数返回值为函数返回值为0。如返回非零值。如返回非零值则表示有错误发生。则表示有错误发生。2.2.文件的关闭文件的关闭文件的关闭文件的关闭1.1.文件的打开文件的打开文件的打开文件的打开82C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写字符读写函数是以字符字符读写函数是以

129、字符(字节字节)为单位的读写函数。每次可从文件为单位的读写函数。每次可从文件读出或向文件写入一个字符。读出或向文件写入一个字符。1. 读字符函数读字符函数fgetcC语言用语言用fgetc函数实现读一个字符,其调用的一般形式为:函数实现读一个字符,其调用的一般形式为: 字符变量字符变量=fgetc(文件指针文件指针);或或 fgetc(文件指针文件指针);函数功能:从指定的文件中读一个字符,并可存入字符变量中。函数功能:从指定的文件中读一个字符,并可存入字符变量中。说明:在说明:在fgetc函数调用中,读取的文件必须是以读或读写方式打函数调用中,读取的文件必须是以读或读写方式打开的。开的。例如

130、:例如:ch=fgetc(fp); 其意义是从打开的文件其意义是从打开的文件fp中读取一个字符并送入中读取一个字符并送入ch中。中。又如:又如:fgetc(fp); 其意义是从打开的文件其意义是从打开的文件fp中读取一个字符,但是读出的字符不保中读取一个字符,但是读出的字符不保存。所以,读取字符的结果也可以不向字符变量赋值。存。所以,读取字符的结果也可以不向字符变量赋值。 1.1.字符读写函数字符读写函数字符读写函数字符读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数4.4.格式化读写函数格式化读写函数格式

131、化读写函数格式化读写函数83C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写在在文文件件内内部部有有一一个个位位置置指指针针。用用来来指指向向文文件件的的当当前前读读写写字字节节。在在文文件件打打开开时时,该该指指针针总总是是指指向向文文件件的的第第一一个个字字节节。使使用用fgetc 函函数数后后,该该位位置置指指针针将将向向后后移移动动一一个个字字节节。 因因此此可可连连续续多多次次使使用用fgetc函函数数,读读取取多多个个字字符符。应应注注意意文文件件指指针针和和文文件件内内部部的的位位置置指指针针不不是是一一回回事事。文文件件指指针针是是

132、指指向向整整个个文文件件的的,须须在在程程序序中中定定义义说说明明,只只要要不不重重新新赋赋值值,文文件件指指针针的的值值是是不不变变的的。文文件件内内部部的的位位置置指指针针用用以以指指示示文文件件内内部部的的当当前前读读写写位位置置,每每读读写写一一次次,该该指指针针均均向向后后移移动动,它它不不需需在在程程序序中中定定义义说说明明,而而是是由由系统自动设置的。系统自动设置的。1.1.字符读写函数字符读写函数字符读写函数字符读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数4.4.格式化读写函数格式化读写

133、函数格式化读写函数格式化读写函数84C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写【例例10.1】读入文件读入文件C1. txt并在屏幕上输出。并在屏幕上输出。程序代码:程序代码:#includemain() FILE *fp; char ch; if(fp=fopen(C1.txt,r)=NULL) printf(Cannot open this filen ); exit(0); else for (ch=fgetc(fp); ch!=EOF ;ch=fgetc(fp) putchar(ch); fclose(fp); 1.1.字符读写函数字

134、符读写函数字符读写函数字符读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数85C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写2. 写字符函数写字符函数fputcC语言用语言用fputc函数实现写一个字符到文件中,其调用的一般形式为:函数实现写一个字符到文件中,其调用的一般形式为: fputc(字符量,文件指针字符量,文件指针); 函数功能:把一个字符写入指定的文件中。函数功能:把一个字符写入指定的

135、文件中。例如:例如:fputc(a,fp);其意义是把字符其意义是把字符a写入写入fp所指向的文件中。所指向的文件中。fputc函数有一个返回值,如写入成功则返回写入的字符,否则返回函数有一个返回值,如写入成功则返回写入的字符,否则返回一个一个EOF。可用此来判断写入是否成功。可用此来判断写入是否成功。EOF是在头文件是在头文件中定义的符号常量,值为中定义的符号常量,值为-1。对于对于fputc函数有以下几点说明:函数有以下几点说明: 待写入的字符量可以是字符常量或字符变量;待写入的字符量可以是字符常量或字符变量; 每写入一个字符,文件内部位置指针向后移动一个字节;每写入一个字符,文件内部位置

136、指针向后移动一个字节; 被写入的文件可以用写、读写、追加方式打开;被写入的文件可以用写、读写、追加方式打开; 用写或读写方式打开一个已存在的文件时将清除原有的文件内容,用写或读写方式打开一个已存在的文件时将清除原有的文件内容,写入字符从文件首开始;写入字符从文件首开始; 如需保留原有文件内容,希望写入的字符以文件末开始存放,必如需保留原有文件内容,希望写入的字符以文件末开始存放,必须以追加方式打开文件,被写入的文件若不存在,则创建该文件。须以追加方式打开文件,被写入的文件若不存在,则创建该文件。 1.1.字符读写函数字符读写函数字符读写函数字符读写函数3.3.数据块读写函数数据块读写函数数据块

137、读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数86C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写【例例10.2】从键盘输入一些字符,逐个把它们送到磁盘上去,直从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个到输入一个#为止。为止。程序代码:程序代码:#include void main() FILE *fp;char ch,l0;scanf(%s,);if(fp=fopen(,w)=NULL) printf(Cannot open fi

138、len);exit(0);ch=getchar();while(ch!=#)fputc(ch,fp);putchar(ch);ch=getchar();fclose(fp); 1.1.字符读写函数字符读写函数字符读写函数字符读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数87C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写1. 读字符串函数读字符串函数fgetsC语言用语言用fgetc函数实现读入一

139、个字符串,其调用的一般形式为:函数实现读入一个字符串,其调用的一般形式为: fgets(字符数组名字符数组名,n,文件指针文件指针);函数功能:从指定的文件中读入一个字符串到字符数组中。函数功能:从指定的文件中读入一个字符串到字符数组中。其中的其中的n是一个正整数,表示从文件中读出的字符串不超过是一个正整数,表示从文件中读出的字符串不超过 n-1个字符。在读入的最后一个字符后加上串结束标志个字符。在读入的最后一个字符后加上串结束标志0。例如:例如:fgets(str,n,fp);其意义是从其意义是从fp所指的文件中读出所指的文件中读出n-1个字符送入字符数组个字符送入字符数组str中。中。 2

140、.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数1.1.字符读写函数字符读写函数字符读写函数字符读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数88C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写【例例10.3】从从test文件中读入一个含文件中读入一个含20个字符的字符串。个字符的字符串。程序代码:程序代码:#includemain() FILE *fp; char str21; if(fp=fopen(test.txt,r)=NULL) pri

141、ntf(Cannot open this filen); exit(1); fgets(str,21,fp); printf(n%sn,str); fclose(fp); 2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数1.1.字符读写函数字符读写函数字符读写函数字符读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数89C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写2. 写字符串函数写字符串函数fputsC语言用语言用fputs函数实现写一个字符

142、串指定文件中,其调用的一般函数实现写一个字符串指定文件中,其调用的一般形式为:形式为: fputs(字符串字符串,文件指针文件指针);函数功能:向指定的文件写入一个字符串。函数功能:向指定的文件写入一个字符串。其中字符串可以是字符串常量,也可以是字符数组名,或指针变其中字符串可以是字符串常量,也可以是字符数组名,或指针变量。量。例如:例如:fputs(“abcd“,fp);其意义是把字符串其意义是把字符串“abcd”写入写入fp所指的文件之中。所指的文件之中。2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数1.1.

143、字符读写函数字符读写函数字符读写函数字符读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数90C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写【例例10.4】从键盘输入字符,并输出到磁盘文件。从键盘输入字符,并输出到磁盘文件。程序代码:程序代码:#includemain() FILE *fp; char str100; if(fp=fopen(test.txt,w)=NULL) printf(Cannot open this file); exit(0); while(strlen(fgets(str)0) fputs(str

144、,fp);fputs(“n“,fp); fclose(fp); 2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数1.1.字符读写函数字符读写函数字符读写函数字符读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数91C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写1. 读数据块函数读数据块函数fread调用形式为:调用形式为:fread(buffer,size,count,fp);函数功能:从指针函数功能:从指针fp当前指向的二进制文件中连续读出当前

145、指向的二进制文件中连续读出countsize个字节的内容,并存入首地址为个字节的内容,并存入首地址为buffer的内存区域的内存区域中。中。2. 写数据块函数写数据块函数fwrite调用形式为:调用形式为:fwrite(buffer,size,count,fp);功能:将首地址为功能:将首地址为buffer的连续的连续countsize个字节的值写入由个字节的值写入由fp指向的二进制文件中去。指向的二进制文件中去。 3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数1.1.字符读写函数字符读写函数字符读写函数字符读写

146、函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数92C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写对以上两个函数的参数说明如下:对以上两个函数的参数说明如下:(1) buffer:是一个指针。对:是一个指针。对fread函数,它是读入数据的存放地函数,它是读入数据的存放地址。对址。对fwrite函数,是要输出数据的地址函数,是要输出数据的地址(以上指的均为起始地以上指的均为起始地址址)。(2) size:要读写的字节数。:要读写的字节数。(3) count:要进行读写多少个:要进行读写多少个size字节的数据项数。字节的数据项

147、数。(4) fp:文件型指针。:文件型指针。如果文件以二进制形式打开,用如果文件以二进制形式打开,用fread和和fwrite函数就可以读写任函数就可以读写任何类型的信息,如:何类型的信息,如:fread(f,sizeof(float),2,fp);其中其中f是一个单精度浮点型数组名,一个单精度浮点型变量占是一个单精度浮点型数组名,一个单精度浮点型变量占4个个字节,这个函数从字节,这个函数从fp所指向的文件读入所指向的文件读入2次次(每次每次4个字节个字节)数据,数据,存储到数组存储到数组f中。中。 1.1.字符读写函数字符读写函数字符读写函数字符读写函数4.4.格式化读写函数格式化读写函数格

148、式化读写函数格式化读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数93C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写【例例10.5】将将100至至200之间的素数存到文件之间的素数存到文件data.txt中。中。程序代码:程序代码:#include #include void main() FILE *fp;int n,r,k;if(fp=fopen(data.txt,wb)=NULL) printf(This not opened! ); exit(0);

149、for(n=101; n200; n=n+2) r=sqrt(n);for(k=2; kr) fwrite(&n,sizeof(int),1,fp);fclose(fp); 1.1.字符读写函数字符读写函数字符读写函数字符读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数94C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写【例例10.6】 将将【例例10.5】生成的数据文件生成的数据文件data.tx

150、t中的素数按每中的素数按每行行10个数输出。个数输出。程序代码:程序代码:#include #include void main() FILE *fp;int n=0,k;if(fp=fopen(data.txt,rb)=NULL) printf(This not opened! ); exit(0); fread(&k,sizeof(int),1,fp);while(!feof(fp) if(n%10=0) printf(n); printf(%6d,k); fread(&k,sizeof(int),1,fp); n+;2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数1.1.

151、字符读写函数字符读写函数字符读写函数字符读写函数4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数95C语言程序设计语言程序设计 (C Programming)9.3 9.3 文件的读写文件的读写fscanf函数,函数,fprintf函数与前面使用的函数与前面使用的scanf和和printf 函数的功能函数的功能相似,都是格式化读写函数。两者的区别在于相似,都是格式化读写函数。两者的区别在于fscanf函数和函数和fprintf函数的读写对象不是键盘或显

152、示器,而是磁盘文件。函数的读写对象不是键盘或显示器,而是磁盘文件。这两个函数的调用格式为:这两个函数的调用格式为:fscanf(文件指针文件指针, 格式字符串格式字符串, 输入表列输入表列);fprintf(文件指针文件指针, 格式字符串格式字符串, 输出表列输出表列);例如:例如:int m,n;fscanf(fp,%d%d,&m,&n);其意义是从其意义是从fp所指向的文件中,取出数据赋给所指向的文件中,取出数据赋给m和和n。int a=128,b=256;fprintf(fp,%3d%5d,a,b);其意义是将其意义是将a和和b的值按格式的值按格式%3d%5d写到写到fp所指向的文件中。

153、所指向的文件中。4.4.格式化读写函数格式化读写函数格式化读写函数格式化读写函数3.3.数据块读写函数数据块读写函数数据块读写函数数据块读写函数1.1.字符读写函数字符读写函数字符读写函数字符读写函数2.2.字符串读写函数字符串读写函数字符串读写函数字符串读写函数96C语言程序设计语言程序设计 (C Programming)9.4 9.4 文件定位函数文件定位函数文文件件的的读读写写操操作作依依赖赖文文件件的的内内部部指指针针,文文件件一一旦旦被被正正确确打打开开,就就会会有有一一个个指指针针指指向向文文件件的的开开始始处处,以以后后每每执执行行一一次次读读写写操操作作指指针针就就会会后后移移

154、一一个个读读写写位位置置,为为下下一一次次读读写写做做好好准准备备。这这种种方方式式被被称称为为“顺顺序序读读写写”。而而实实际际应应用用中中,往往往往需需要要对对文文件件进进行行随随机机读读写写,这这就就需需要要人人为为地地移移动动指指针针。C语语言言提提供供了了文文件件定定位位函函数,可移动指针到需要处。数,可移动指针到需要处。函数调用格式:函数调用格式:rewind(文件指针文件指针); 函数功能:移动文件指针到文件的开始处,函数无返回值。函数功能:移动文件指针到文件的开始处,函数无返回值。1.1.重置文件指针函重置文件指针函重置文件指针函重置文件指针函数数数数3.3.取指针位置函数取指

155、针位置函数取指针位置函数取指针位置函数2.2.设置指针位置函设置指针位置函设置指针位置函设置指针位置函数数数数97C语言程序设计语言程序设计 (C Programming)9.4 9.4 文件定位函数文件定位函数【例例10.7】 将将file1的内容输出到屏幕上,并将其写到的内容输出到屏幕上,并将其写到file2中。中。程序代码:程序代码:#include void main() FILE *fp1,*fp2; char ch; fp1=fopen(,r); fp2=fopen(,w); ch=fgetc(fp1);while(!feof(fp1) /*将将file1的内容输出到屏幕上的内容输

156、出到屏幕上*/ putchar(ch);ch=fgetc(fp1); rewind(fp1); /*将将file1的指针移到开始处的指针移到开始处*/ ch=fgetc(fp1);while(!feof(fp1) /*将将file1的内容写到的内容写到file2中中*/ fputc(ch,fp2);h=fgetc(fp1); fclose(fp1); fclose(fp2); 1.1.重置文件指针函重置文件指针函重置文件指针函重置文件指针函数数数数3.3.取指针位置函数取指针位置函数取指针位置函数取指针位置函数2.2.设置指针位置函设置指针位置函设置指针位置函设置指针位置函数数数数98C语言程

157、序设计语言程序设计 (C Programming)9.4 9.4 文件定位函数文件定位函数函数调用格式:函数调用格式:fseek(fp, n,tag);函数功能:将文件指针移动到离文件开始处的第函数功能:将文件指针移动到离文件开始处的第n 个字节处。个字节处。其中其中fp为文件指针;为文件指针;n为位移的字节数,须为长整型;为位移的字节数,须为长整型;tag代表位代表位移的基点,移的基点,tag=0时代表文件开始处,时代表文件开始处,tag=1时代表文件当前时代表文件当前位置,位置,tag=2时代表文件的尾。时代表文件的尾。例如:例如:fseek(fp,100L,0); /*将指针移动到第将指

158、针移动到第100个字节处个字节处fseek(fp,-80L,1); /*将指针从当前的第将指针从当前的第100个字节处头移动个字节处头移动80个个字节,即第字节,即第20个字节处个字节处fseek(fp,60L,2); /*将指针移动到文件倒数第将指针移动到文件倒数第60个字节处个字节处使用时应注意,使用时应注意,fseek函数仅适用于二进制文件,若用于函数仅适用于二进制文件,若用于ASCII文文件时,由于字符在输入输出时需要做内码转换,会造成位置出件时,由于字符在输入输出时需要做内码转换,会造成位置出错而使错而使fseek函数调用失败。函数调用失败。2.2.设置指针位置函设置指针位置函设置指

159、针位置函设置指针位置函数数数数3.3.取指针位置函数取指针位置函数取指针位置函数取指针位置函数1.1.重置文件指针函重置文件指针函重置文件指针函重置文件指针函数数数数99C语言程序设计语言程序设计 (C Programming)9.4 9.4 文件定位函数文件定位函数函数调用格式:函数调用格式:ftell(文件指针)(文件指针);函数功能:用来取得文件流目前的读写位置。返回值为长整型的函数功能:用来取得文件流目前的读写位置。返回值为长整型的当前读写位置,若有错误则返回当前读写位置,若有错误则返回-1。例如:例如:fseek(fp,-60L,1);if (ftell(fp)=-1L) /*若指针

160、位置有错,则给出提示信息,并结若指针位置有错,则给出提示信息,并结束程序执行束程序执行*/ printf(“Error!n); exit(0); 3.3.取指针位置函数取指针位置函数取指针位置函数取指针位置函数2.2.设置指针位置函设置指针位置函设置指针位置函设置指针位置函数数数数1.1.重置文件指针函重置文件指针函重置文件指针函重置文件指针函数数数数100C语言程序设计语言程序设计 (C Programming)9.5 9.5 文件出错检测函数文件出错检测函数函数调用格式:函数调用格式:ferror(文件指针文件指针); 函数功能:检查文件在用各种输入输出函数进行读写时是否出错。函数功能:检

161、查文件在用各种输入输出函数进行读写时是否出错。如如ferror返回值为返回值为0表示未出错,否则表示有错。表示未出错,否则表示有错。例如:例如:if(ferror(fp) printf(“t i/on”); fclose(fp); exit(0); 其中,调用其中,调用fopen函数时,函数时,ferror函数初值自动置为函数初值自动置为0。对同一个。对同一个文件,每次调用文件,每次调用ferror函数都会产生一个新的函数都会产生一个新的ferror函数值与函数值与之对应,因此对文件执行一次读写后,应及时检查之对应,因此对文件执行一次读写后,应及时检查ferror函数函数的值是否正确,以避免数

162、据的丢失。的值是否正确,以避免数据的丢失。 1.1.读写出错检测函读写出错检测函读写出错检测函读写出错检测函数数数数2.2.清除文件出错标清除文件出错标清除文件出错标清除文件出错标志函数志函数志函数志函数3.3.清除文件函数清除文件函数清除文件函数清除文件函数101C语言程序设计语言程序设计 (C Programming)9.5 9.5 文件出错检测函数文件出错检测函数若对文件读写时出现错误,若对文件读写时出现错误,ferror函数就返回一个非零值,而且函数就返回一个非零值,而且该值一直保持到对文件的下一次读写为止。该值一直保持到对文件的下一次读写为止。Clearerr函数能清函数能清除出错标

163、志,使除出错标志,使ferror函数值复位为函数值复位为0。函数调用格式:函数调用格式:clearerr(文件指针文件指针); 函数功能:本函数用于清除出错标志和文件结束标志,使它们为函数功能:本函数用于清除出错标志和文件结束标志,使它们为0值。值。 2.2.清除文件出错标清除文件出错标清除文件出错标清除文件出错标志函数志函数志函数志函数1.1.读写出错检测函读写出错检测函读写出错检测函读写出错检测函数数数数3.3.清除文件函数清除文件函数清除文件函数清除文件函数102C语言程序设计语言程序设计 (C Programming)9.5 9.5 文件出错检测函数文件出错检测函数当文件操作出现错误的

164、时候,为了避免数据丢失,正常返回操作当文件操作出现错误的时候,为了避免数据丢失,正常返回操作系统,可以调用过程控制函数系统,可以调用过程控制函数exit关闭文件,终止程序的执行。关闭文件,终止程序的执行。函数调用格式:函数调用格式:exit(status);函数功能:清除并关闭所有已打开的文件,写出文件缓冲区的所函数功能:清除并关闭所有已打开的文件,写出文件缓冲区的所有数据,程序按正常情况由有数据,程序按正常情况由main函数结束并返回操作系统。函数结束并返回操作系统。其中其中status为状态值,它被传递到调用函数。若为状态值,它被传递到调用函数。若status取零值,取零值,表示程序正常终止,否则表示因错而终止。若缺省无返回值。表示程序正常终止,否则表示因错而终止。若缺省无返回值。3.3.清除文件函数清除文件函数清除文件函数清除文件函数1.1.读写出错检测函读写出错检测函读写出错检测函读写出错检测函数数数数2.2.清除文件出错标清除文件出错标清除文件出错标清除文件出错标志函数志函数志函数志函数103

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 资格认证/考试 > 自考

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