目录
C语言要素
-
字符集
字母(A~Z,a~z),数字(0~9),特殊字符(29个图形字符),空白符(空格符,回车符,换页符,横向制表符,纵向制表符)
29个图形字符:+,-,*,/,%,<,>,!,&,|,^,~,_,·,(,),[,],{,},?,:,;,,,",',#,\
-
标识符与关键字
标识符:只能由字母数字下划线组成,第一个字符必须是字母或者下划线,长度只有31个字符有效,不能包含空格,不能使用关键字
关键字(标准C包含32个关键字):数据类型说明符(12个),流程控制说明符(12个),存储类型说明符(4个,auto、extern、register、static),其他类型(4个,const、sizeof、typedef、volatile)
关键字必须是小写,关键字有固定含义不可改变
-
可执行语句
语句是构成程序的基本单位,C程序中的语句必须以分号结束。
常用语句:声明语句,表达式语句,程序控制语句,复合语句,函数调用语句。
数据类型
数据类型:基本类型,构造类型,指针类型,空类型void
基本类型:整型(int),字符型(char),浮点型(单精度型float,双精度型double)
构造类型:数组类型(array),结构类型(struct),枚举类型(enum)
1字=2字节/4字节(B),1字节=8比特
变量的定义:类型 变量名 【变量值】; {变量名需符合标识符定义规则}
#define 标识符 常量 {符号常量没有数据类型,值不能改变,注意语句后面没有分号}
-
变量
-
常量
-
整型数据
整型常量:{整型常数可以添加后缀u/U,l/L表示无符号和长整数}
十进制 | 0~9,+,- | 无前缀 |
八进制 | 0~7 | 前缀0 |
十六进制数 | 0~9,A~F/a~f | 前缀0X/0x |
整型变量:基本整型:int,4个字节(32位机)默认类型
短整型:short 【int】,2个字节(32位机);
长整型:long 【int】,4字节。
无符号型:unsigned,范围扩大一倍。
特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较:
类型\平台 | 16位平台 | 32位平台 | 64位平台 |
char | 1个字节8位 | 1个字节8位 | 1个字节 |
short | 2个字节16位 | 2个字节16位 | 2个字节 |
int | 2个字节16位 | 4个字节32位 | 4个字节 |
long | 4个字节32位 | 4个字节32位 | 8个字节(区别) |
long long | \ | 8个字节64位 | 8个字节 |
指针 | 2个字节16位 | 4个字节32位 | 8个字节(区别) |
虽然大部分情况栈的生长方向自上向下,但是数组的方向都是向上生长的;小端存储,高字节放高地址,低字节放低地址;大段存储相反
-
浮点型数据
单精度(float型,4字节,小数点后六位有效)双精度(double型,8字节,15位,默认类型)扩展的双精度(long double型)
浮点型常量:
1)小数形式:0~9,小数点,正负号。注意:小数点前面或者后面的数为0可以省略一个0,但不能同时省略,而且必须要有小数点。
2)指数形式:0~9,阶码标志e/E,阶码。一般形式:aEn(a为小数,n为整数,可以带符号)。
可以添加后缀f/F,l/L表示float型和long double型,无后缀默认double型。输出%f,分别用%f,%lf对float型和double型输入。
-
字符型数据
单引号括起来的一个字符 ,特殊的,转义字符。 \ddd八进制数表示的字符数,\xhh十六进制数表示的字符数。
大小写字母ASCⅡ码差32,即'A'+32='a'。
字符串会自动再串尾加特殊字符'\0',作为字符串的终止标志,因此"A"实际包含两个字符,'A'只包含一个字符。
输入输出操作
格式化输出函数:printf("格式化控制字符串",arg1,arg2……);
printf("i=%d\n",i);
d十进制,o八进制,x/X十六进制,u无符号数,f小数,e/E指数,c单个字符,s字符串
整数的格式化输出
%[对齐方式][输出最小宽度]整数类型
1)输出最小宽度:%nd(实际位数大,输出实际位数,实际位数小,补以空格或0)
2)对齐方式:%d或%-d(默认右对齐,加负号左对齐)
实数的格式化输出
%[输出宽度][.精度]实数类型
1)输出最小宽度:%nf(实际位数大,输出实际位数,实际位数小,补以空格或0,默认右对齐,加负号左对齐)
2)精度:%n.mf(用以显示小数点后面的整数m,若实际位数大于定义的位数,四舍五入)
f=-00000001f;printf("%e\n",f); 输出结果:1.000000e-008
格式化输入函数:scanf("格式化控制字符串",&arg1,&arg2……);
scanf("%d%d",&i,&j);//输入1 2 scanf("%d,%d",&i,&j);//输入1,2
字符的输入与输出
- 输入字符:
1)scanf,使用格式字符%c 。
2)调用非格式化输入函数getchar,其功能是读字符。char c=getchar();
两种形式都可以输入任意字符包括空格制表符和回车。
int i;float f;char c;
scanf("%d%f%c",&i,&f,&c);
printf("%c,%d",c,c);
/*输入1(空格)3.14(回车)后,将输出回车和10。
因为3.14后的回车不是分隔符而是有效字符*/
因此当输入数值型数据后,想继续输入字符型数据时,必须先接收前面遗留的分隔符,才能成功输入新的有效字符。
int i;float f;char c;
scanf("%d%f",&i,&f);
c=getchar();
c=getchar();
printf("%i,%f,%c",i,f,c);
/*输出1,3.14,A*/
接收空格并输入字符还可以写成如下形式:getchar();c=getchar();或scanf("%c",&c); scanf("%c",&c);
- 输出字符:
1)printf,使用格式字符%c 。
2)调用非格式化输入函数putchar,其功能是输出单个字符。getchar(字符数据); putchar('A');
getchar函数只能接收单个字符,使用这两个函数时需写头函数stdio.h。char c=getchar();putchar();==putchar(getchar());
运算符分类
算术运算符(加减乘除,求余,自增,自减),
关系运算符(>,<,==,!=,>=,<=)低于算术运算符高于赋值运算符,
逻辑运算符(&&,||,!)赋值运算符<&&,||<关系运算符<算术运算符<!,
位操作运算符(&,|,~,^,<<,>>),
赋值运算符(=,+=,-=……),
条件运算符(?:)优先级低于关系运算符和算术运算符高于赋值运算符,结合方向自右至左,
逗号运算符(,)优先级最低,
指针运算符(&取地址,*取内容),
求字节数运算符(sizeof),
其他运算符(括号,下标,成员等)。
逗号运算符<赋值运算符<&&,||,条件运算符<关系运算符<算术运算符<!,单目运算符高于双目运算符
其他
注意:
1)除法运算中除数不能为0,求模运算的操作数必须为整型。
2)<math.h> abs()求绝对值,sqrt()求平方根,三角函数
3)<ctype.h> isalpha判断一个字符是否为字母,tolower将变量ch转换为小写字母
4)由于计算机不能精确表示所有实数,不建议使用==比较两数大小,建议通过求两者差的绝对值来比较。
类型转换
- 隐式类型转换:(char,short->int->unsigned->long->double,float->double)
- 显示类型转换:(类型说明符)(表达式)
Switch语句
语法规则:switch(表达式){case 标号1:语句1;break;……default:语句n+1}
break跳出循环;continue跳出本次循环;goto 标号;标号:语句;
产生随机数
语法规则:rand()%100+1,1~100的随机数。为防止每次运行程序产生的数字重复,可使用<stdlib.h>中的srand函数。
#include<stdlib.h>
#include<time.h>
srand(time(0));
magic=rand()%100+1;
辗转相除法
while(itemp!=0)
{
itemp=inum1%inum2;
inum1=inum2;
inum2=itemp;
}
函数参数
- 1)函数调用中发生的数据传送是单向的即实参->形参;形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。
- 2)数组作为函数参数。数组元素作为函数参数,和普通变量一样;数组名作为函数参数,传递的是地址。
可省去函数声明的情况
- 被调函数返回值为整型或字符型
- 被调函数定义出现在主调函数前
- 在所有函数定义前,在函数外预先说明各函数的类型
- 调用库函数
变量:
全局变量(静态存储) 又叫外部变量
在函数中使用函数之后定义的全局变量,加说明符extern;在函数之前定义可不加说明
局部变量(动态存储)
变量存储类型:自动变量auto,寄存器变量register,外部变量extern,静态变量static
extern类似函数声明,是对已经存在的外部变量声明,剩下三个为定义。
静态变量属于静态存储方式,外部变量虽然属于静态存储方式,但不一定是静态变量。静态变量生存周期为整个程序,在编译时赋初值,只赋初值一次。静态全局变量的作用域局限于一个文件内。
指针运算符*
int *p=&i;
- (&取地址,*取内容)*可以表示类型说明符也可以表示间接访问运算符
- 不能用一个数给指针变量赋值,下面赋值是错误的: int *pi1; pi1=20; 但是,指针可用0赋值,代表空指针,哪里也不指向。
- 给指针变量赋值时,指针变量前不能加“*”说明符,下面的写法是错误的:
int i1; int *pi1; *pi1=&i1; 指针变量pi1前面加*就代表间接访问了,代表i1。
- 指针变量未指向具体有效地址,间接访问会有问题
int *pi1; /* 指针变量pi1未赋值,不知道指向哪里*/ *pi1=200; /* 向pi1所指向的地址空间赋值200 */
指针与数组
- 数组名代表数组的首地址,即第0号元素的地址
- ++,--,+,-,指pi地址值位置跳过i个字节后的地址
例:int iarr[5]={0,1,2,3,4};int *pi=&iarr[1];pi++,pi的值为&iarr[2]
*pi++,先*pi,再++,表达式值为iarr[1],pi的值为&iarr[2]。
*++pi,先pi+1,再*pi,表达式值为iarr[2],pi的值为&iarr[2]。
(*pi)++,先*pi,再(*pi)++,表达式值为iarr[1]+1,iarr[1]值改变,pi的值为&iarr[1],pi的值不变。
int *pi2=&iarr[2];int *pi3=&iarr[4];
pi3-pi2=2返回值不是相差字节数,而是相差整数的个数。
注意:pi+i1指向的是iarr[i1]的地址,*(pi+i1)指向的是数组元素,即iarr[i1]。
二维数组
iarr[i1]有两层含义,它既是“一维数组iarr”的数组元素,又是一维数组名。
#include <stdio.h>
void swap(int *pi1Copy,int *pi2Copy)
{
int *piTemp;
/*交换形参指针变量,实参不受影响*/
piTemp=pi1Copy;
pi1Copy=pi2Copy;
pi2Copy=piTemp;
}
#include <stdio.h>
void swap(int *pi1Copy,int *pi2Copy)
{
int iTemp=0;
/*交换形参指针变量所指向的变量,
实参不受影响,但是实参所指向
数据改变了*/
iTemp=*pi1Copy;
/*用的间接访问,实际上是访问i1、i2*/
*pi1Copy=*pi2Copy;
*pi2Copy=iTemp;
}
数组名作为函数参数
数组名就是数组的首地址,实参向形参传递数组名实际上就是传递数组的地址。
指向函数的指针
一般形式:类型说明符 (*指针变量名)(参数表);
int (*pf)(int,int);//定义函数指针
pf=max;//函数名赋值给函数指针变量
i3=(*pf)(i1,i2);//通过函数指针调用函数
字符串
- 字符串以'\0'结束,系统自动添加。
- %s,输出字符串。
- 用scanf函数输入字符串时,字符串不能含有空格,否则将以空格作为串的结束符。解决办法,gets()函数。如scanf("%s",carr2);注意carr2不用加&,本身已经是地址。
- 当指针指向字符串常量时,不允许更改字符串中的字符,但更改指针允许。
字符型指针变量还可以指向字符串常量。如: char *pc="C Language"; 表示pc是一个指向字符型的指针变量,把字符串的首地址赋予pc。 还可以写为: char *pc; pc="C Language";
需要注意的是,字符型指针变量本身是一个变量,用于存放字符串的首地址。而字符串常量本身是存放在以该首地址为首的一块连续的内存空间中并以‘\0’作为串的结束,字符串常量本身本身是不能被更改的。
对字符串存储,有用字符型指针变量指向字符串常量和按照字符数组存储两种方式,注意这两种方式的差异:
(1)字符型指针变量指向字符串常量方式:
char *pc="C Language";
读取其中字符是允许的:
char c1=pc[3]; /* 允许*/
因为指向的是字符串常量,所以,写入是不允许的:
pc[3]= 'A'; /* 不允许*/
更改字符型指针变量也是允许的:
pc="BASIC"; /* 允许*/
pc不再指向字符串常量"C Language",而是指向字符串常量"BASIC"。
(2)字符数组方式:
char cArr[11]= "C Language";
读写其中字符都是允许的:
char c1=cArr[3]; cArr[3]= 'A'; /* 都允许*/
数组名是不允许更改的:
cArr="BASIC"; /* 不允许*/
字符串函数
头文件<stdio.h>
- 字符串输出函数:int puts(const char *pc);空字符不输出,但输出换行符及空格等分隔符。
- 字符串输入函数:char *gets(char *pc);遇到换行符或输入文档结束符,并丢弃换行符或结束符,然后在自符数组中添加一个空字符。不可以使用指针变量指向字符串常量,因为常量空间不允许改变。
char *pc="C Language";gets(pc);报错
atoi函数把数字构成的字符串转换为整数。
头文件<string.h>
- int strlen(const char *pc);返回字符串长度
- char *strcat(char *pc1,const char *pc2);字符串连接pc1后加pc2
- char *strcpy(char *pc1,const char *pc2);把pc2复制到pc1
- char *strcmp(const char *pc1,const char *pc2);按照ascll码顺序比较两个字符串大小,值=0,相等;值>0,左边大;值<0,左边小。A+32=a。
- char *strstr(const char *pc1,const char *pc2);字符串查找,返回pc1中第一次出现pc2的地址,不出现返回空指针。
动态空间管理
在变量存储类别部分,介绍过C语言内存分为3个区,有了字符串和动态空间后可以把它增加到5五个区:
动态存储区(栈):用来存放函数的形参和函数内的局部变量。函数调用时分配空间,在函数执行完后由编译器自动释放。
堆区:用来存放由动态分配函数(如malloc)分配的空间。是由动态分配函数分配的,并且必须使用free释放。如果忘记用free释放,会导致所分配的空间一直占着不放,导致内存泄露。
静态存储区:用来存放全局变量和静态变量。存在于程序的整个运行期间。
字符串常量区:例如char *c = “123456”;则”123456”为字符串常量,存放于字符串常量区。存在于程序的整个运行期间。不同函数使用同的字符串常量在内存中会共用。
程序代码区:用来存放程序的二进制代码。
头文件<stdlib.h>
- malloc函数:开辟指定大小的存储空间,并返回该存储区的起始地址。 若size超出可用空间,则返回空指针值NULL。
//void *malloc(unsigned int size); int *pi; pi=(int *)malloc(10*sizeof(int));
- calloc函数:按所给数据个数和每个数据所占字节数开辟存储空间。
//void *calloc(unsigned int num, unsigned int size); int *pi; pi=(int *)calloc(10,sizeof(int));
- realloc函数:重新定义所开辟内存空间的大小。 ptr所指的内存空间是之前开辟的,size为新空间大小。
//void *realloc(void *ptr, unsigned int size) float *pf; pf=(float*)malloc(8); pf=(float *)realloc(pf,16);
- free函数:将以前开辟的某内存空间释放。 void free(void *ptr)
//void free(void *ptr); free(pf);
结构体
定义:
struct stu{
int num;char name[20];
};
struct stu str1,str2;
struct stu{
int num;char name[20];
}str1,str2;
struct {
int num;char name[20];
}str1,str2;
可嵌套结构体,即结构体的成员也是结构体。
初始化:
在定义时初始化赋值
struct stu{
int num;
char name[20];
}str2,str1={1,"zyc"};
引用:
结构体变量名.成员名,例,st1.num
结构体变量赋值:
str2=str1;
注意:输出结构体时,不能整体输出,只能依次输出其成员
结构体与指针
一般形式:struct 结构名 * 结构指针变量名;
struct stu *p;
p=&str1;
注意:结构体变量名代表的是一个结构体,而不是结构体变量的地址,所以需要加&。
结构体指针变量,间接访问成员:(*p).num;或p->num;
枚举
一般形式:enum 枚举名{枚举值表};
enum weekday{sun,mon,tue,wed,thu,fri,sat};
//weekday类型变量的取值只能是七天中的某一天
枚举变量的定义:
enum weekday{sun,mon,tue,wed,thu,fri,sat};enum weekday weel1;
enum weekday{sun,mon,tue,wed,thu,fri,sat}weel1;
enum {sun,mon,tue,wed,thu,fri,sat}weel1;
枚举类型优点: 1.便于理解、见名知义 2.节省存储空间
枚举类型缺点: 1.编程复杂 2.程序运行费时间
注意:
- 枚举值是一种特殊的常量值,不是变量,不能再次赋值。
- 枚举元素本身由系统定义了一个表示序号的数值,从0开始顺序定义,在weekday中,sun的序号值为0。
- 枚举元素不是字符串常量也不是字符常量,使用时不可加单双引号。
- 枚举类型变量输出时无法直接输出枚举元素,若需输出枚举元素,可使用switch语句。
//例12.6 枚举类型输入输出
#include <stdio.h>
enum weekday
{ sun,mon,tue,wed,thu,fri,sat};
int main()
{ int i1;
enum weekday enumWeek[3];
enumWeek[0]=sun;
enumWeek[1]=mon;
enumWeek[2]=tue;
/*输出枚举变量值*/
printf("%d,%d,%d\n",enumWeek[0],enumWeek[1],enumWeek[2]);
/*输出枚举变量元素值*/
for(i1=0;i1<=2;i1++)
switch(enumWeek[i1])
{
case sun:printf("%s\n","sun");break;
case mon:printf("%s\n","mon");break;
case tue:printf("%s\n","tue");break;
case wed:printf("%s\n","wed");break;
case thu:printf("%s\n","thu");break;
case fri:printf("%s\n","fri");break;
case sat:printf("%s\n","sat");break;
}
return 0;
}
链表
链表的基本操作有以下几种: (1) 建立链表; (2) 输出链表 (3) 结点查找; (4) 插入结点; (5) 删除结点;
//例12.5 链表的创建、输出、查找
#include <stdio.h>
/*结点定义*/
struct student
{
int iNum;
float fScore;
struct student *pStrNext;
};
/*创建链表*/
struct student * create()
{ struct student *pStrStuHead=0,*pStrStuTemp,*pStrStuTail=0;
int iNumTemp;
float fScoreTemp;
printf("input num and score(>=0, <0 end):\n");
scanf("%d",&iNumTemp);
scanf("%f",&fScoreTemp);
/* 添加结点,当输入成绩值为负数时结束 */
while(fScoreTemp>0)
{ /*申请结点并填入数据,结点的指针域为0,因为新结点将作为最后一个结点*/
pStrStuTemp=(struct student*)malloc(sizeof(struct student));
pStrStuTemp->iNum=iNumTemp;
pStrStuTemp->fScore=fScoreTemp;
pStrStuTemp->pStrNext=0;
/*接入链表*/
if(!pStrStuHead)
/*接入第一个结点,头指针、尾指针均指向该结点*/
pStrStuHead=pStrStuTail=pStrStuTemp;
else {
/*接入非第一个结点*/
pStrStuTail->pStrNext=pStrStuTemp;/*接在尾指针所指结点之后*/
pStrStuTail=pStrStuTemp;/*尾指针指向新加入结点*/ }
printf("input num and score(>=0, <0 end):\n");
scanf("%d",&iNumTemp);
scanf("%f",&fScoreTemp); }
return pStrStuHead; }
/*输出链表*/
void list(struct student *pStrStuHead)
{
while(pStrStuHead)
{
printf("%d\t%f\t\n",pStrStuHead->iNum,pStrStuHead->fScore);/*输出*/
pStrStuHead=pStrStuHead->pStrNext;/*移动到下一个结点*/
}
}
/*查找结点*/
struct student *search(struct student *pStrStuTemp,float fScoreTemp)
{
while(pStrStuTemp)
{
if(pStrStuTemp->fScore==fScoreTemp)
break;
pStrStuTemp=pStrStuTemp->pStrNext;/*移动到下一个结点*/
}
return pStrStuTemp;
}
int main()
{
struct student strStuTemp;
struct student *pStrStuHead,*pStrStuResualt=0;
float fScoreTemp;
int iNumTemp;
/*创建链表*/
pStrStuHead=create();
/*输出链表所有结点*/
list(pStrStuHead);
/*输入要查找的成绩,然后返回找到结点的地址,找不到返回空*/
printf("input search score:\n");
scanf("%f",&fScoreTemp);
pStrStuResualt=search(pStrStuHead,fScoreTemp);
if(pStrStuResualt)
printf("num=%d,score=%f\n",pStrStuResualt->iNum,pStrStuResualt->fScore);
else
printf("not found!");
return 0;
}
文件
-
打开文件
fopen函数用来打开一个文件,其调用的一般形式为: 文件指针名=fopen(文件名,使用文件方式);
-
FILE *fp; fp=fopen("C:\\file.text","rb"); /*其意义是打开C驱动器磁盘的根目录下的文件file, 这是一个二进制文件,只允许按二进制方式进行读操作。 两个反斜线“\\ ”中的第一个表示转义字符,第二个表示根目录。*/
文件打开方式
意 义
r
只读打开一个文本文件,只允许读数据
w
只写打开或建立一个文本文件,只允许写数据
a
追加打开一个文本文件,并在文件末尾写数据
rb
只读打开一个二进制文件,只允许读数据
wb
只写打开或建立一个二进制文件,只允许写数据
ab
追加打开一个二进制文件,并在文件末尾写数据
r+
读写打开一个文本文件,允许读和写
w+
读写打开或建立一个文本文件,允许读写
a+
读写打开一个文本文件,允许读,或在文件末追加数据
rb+
读写打开一个二进制文件,允许读和写
wb+
读写打开或建立一个二进制文件,允许读和写
ab+
读写打开一个二进制文件,允许读,或在文件末追加数据
-
关闭文件
fclose函数用来关闭文件,其调用的一般形式是: fclose(文件指针);
fclose(fp); /*正常完成关闭文件操作时,fclose函数返回值为0。如返回EOF则表示有错误发生。*/
字符读写函数 :fgetc和fputc
字符串读写函数:fgets和fputs
数据块读写函数:fread和fwrite
格式化读写函数:fscanf和fprinf
-
读字符函数fgetc
一般形式:int fgetc(FILE *stream);
函数功能:从指定的文件中读一个字符。
函数参数:stream为指向文件的指针。
函数返回值:从stream所指的文件流中读取一个字符,转换为int类型返回。若已到文件尾返回EOF,文件状态改为结束状态。若读错误则返回EOF,文件改为错误状态。EOF在stdio.h中定义为-1。例如: ch=fgetc(fp);
-
写字符函数fputc
一般形式:int fputc(int ch,FILE *stream);
函数功能:将ch对应字符写到stream指定的文件中。
函数参数:ch为将要写出的字符;stream指向写出字符文件的指针。
函数返回值:返回写出的字符,转换为int类型返回。若写错误则返回EOF,文件改为错误状态。 例如: fputc('x',fp);
-
读字符串函数fgets
一般形式:char *fgets(char *string, int n, FILE *stream);
函数功能:从stream指向的文件中读n-1个字符构成的字符串到string对应的字符数组中,在读入的最后一个字符后加上串结束标志'\0'。若未读够n-1字符而遇到换行符时,读取也将结束。
函数参数:string为要写入字符串的空间的起始地址;n为字符串空间的长度;stream指向读入字符文件的指针。
函数返回值:返回由文件中读出的字符串。 例如:fgets(cArr,11,fp);
-
写字符串函数fputs
一般形式:int fputs(char *string, FILE *stream);
函数功能:向stream指向的文件写入一个字符串string。
函数参数:string为要写入文件的字符串;stream指向写出字符串的文件指针。
函数返回值:写入成功返回非负值,若写入错误,则返回EOF。 例如:fputs("C Language",fp); 其含义是把字符串"C Language"写入fp所指的文件之中。
-
写数据块函数fwrite
一般形式:int fwrite(void *ptr, int size, int items, FILE *stream);
函数功能:把ptr指向的地址(通常为数组)中items个size的内容写到向stream指向的文件中。
函数参数:ptr为要写出首地址;size为每一个数据元素长度;items为数据元素个数;stream为写出文件的指针。
函数返回值:返回成功写出数据元素的个数items,若出现写错误时,结果将小于items。
-
读数据块函数fread
一般形式: int fread(void *ptr, int size, int items, FILE *stream);
函数功能:由stream指向的文件中读出items个size的内容写到ptr指向的数组中。
函数参数:ptr为要写入首地址;size为每一个数据元素长度;items为数据元素个数;stream为读入文件的指针。
函数返回值:返回读入数据元素的个数items,若读入过程中遇到结束标志,结果将小于items。 double buffer[10]; fread(buffer,8,10,fp); 其含义是从fp所指的文件中,每次读8个字节(一个double)送入double数组buffer中,连续读10次,即读10个double到buffer中。
-
格式化读写函数
fscanf 函数和fprintf函数的读写对象不是键盘和显示器,而是磁盘文件。
调用格式为: fscanf(文件指针,格式字符串,输入表列); fprintf(文件指针,格式字符串,输出表列);
int i1=5; float f1=3.6; fprintf(fp,"%d%f",i1,f1); fscanf(fp,"%d%f",&i1,&f1);
-
文件的随机读写
文件定位移动文件内部位置指针的函数主要有两个,即rewind 函数和fseek函数。
rewind函数调用形式为: rewind(文件指针); 它的功能是把文件内部的位置指针移到文件首。
fseek函数调用形式为: fseek(文件指针,位移量,起始点);
fseek函数用来移动文件内部位置指针
起始点 | 表示符号 | 数字表示 |
文件首 | SEEK_SET | 0 |
当前位置 | SEEK_CUR | 1 |
文件末尾 | SEEK_END | 2 |
文件检测函数
- 文件读写错误检测函数 ferror
在调用各种输入输出函数(如 fputc、fgetc、fread、fwrite 等)时,如果出现错误,则除了函数返回值有所反映外,还可以用 ferror 函数检查,
它的一般调用形式为:ferror(fp);
如果 ferror 返回值为 0(假),则表示未出错。如果返回一个非 0 值,则表示出错。
- 文件结束检测函数feof
读文件时遇到文件尾就应该结束,所以读取文件时经常需要判断是否到文件尾。可以利用feof函数判断是否到文件尾。它的一般函数调用形式为
它的一般调用形式为:feof(文件指针);
如文件结束,则返回值为非0,否则为0。