STM32——C语言基础

1.C语言数据类型

基本类型整型(短整型short,整形int,长整型long)
实型(浮点型),包括单精度型float,双精度型double
字符型char
枚举类型 enum
构造类型数组类型
结构体类型
共用体类型
指针类型
空类型void

数据类型决定了数据占据内存字节数,数据的取值范围以及可以进行的操作

2.常量与变量

在程序运行时不能改变的量称为常量,用来表示常量的变量称为符号常量,程序中用#define定义的就是常量,不可更改

#define PRICE 30;
#include <stdio.h>
void main(){
    int num, total;
    num=10;
    total=num*PRICE;
//这里PRICE不可更改
    printf("total=%d\n",total);
}

变量:
定义:其值可以改变的量

定义格式:数据类型  变量名

变量要有名字,并在内存中占据一定的存储单元,变量名实际上是一个内存地址

标识符:
定义:表示变量名,符号常量名,函数名,数组名文件名的字符串序列

命名规则:

(1)只能由字母,数字,下划线组成,第一个字符必须是字母或者下划线

(2)区分大小写

(3)不能使用关键字

使用方法:先定义,后使用

整型常量的三种表示方法

十进制整数数字0-9和正负号表示,如123,-90
八进制整数数字0开头,后面跟0-7表示,如0123,011等
十六进制整数

有0x开头,后面跟0-9,a-f,A-F,如0x123,0xff

数据在内存中的存放形式

内存以字节为单位,一个字节8个二进制位,每个二进制位是0或者1

有符号数值的表示方法——原码,反码和补码

原码:最高位为符号位,其余各位为数值本身的绝对值

反码:
        正数:反码与原码相同

        负数:符号位为1,其余位对原码取反

补码:

        正数:原码,反码,补码相同

        负数:最高位为1,其余位为原码取反,再对整个数加1

整型数据再内存中以二进制补码形式存放

三类整型变量

有符号无符号
基本型(简称整型)intunsigned int
短整型short或short intunsigned short
长整型long或long intunsigned long

整型类型和取值范围

所占位数最小取值范围
int32-2147483648~+2147483647
short16-32768~+32767

long

32-2147483648~+2147483647
unsigned int320-4694967295
unsigned short160-65535
unsigned long320-4294967295
#include <stdio.h>
void main(){
    short a, b;
    int c;
    a=32767;
    b=a+1;
    c=a+1;
    printf("%d,%d\n",b,c);//-32768,32768
//这里产生溢出
}

浮点型数据

表示方法:

小数形式:0.123  指数形式:3e-3

字符常量:
定义:单引号括起来的单个字符或者转义字符

字符常量的值:该字符的ASCII码

定义格式:char 变量名=值

转义字符:反斜杠加字符

对字符数据进行算数运算,实质是对其ASCII码进行算数运算

字符串常量:

定义:“ ”中的内容

C语言规定每一个字符串常量接为加一个“字符串结束标志”,以便系统判断字符串是否结束,C规定字符'\0'作为字符串结束标志

比如字符串常量“CHINA”,在内存中是CHINA0

各类数值型数据间的混合运算

整型,浮点型可以混合运算,在混合运算时,不同类型先转换为同一类型,然后进行运算,这种类型转换是系统自动进行,字节数少的往字节数高的方向转换

强制转换:数据类型(要转换的变量)

float x,y z;
int i,j;
x=1.56;
y=2.34;
i=x+y;
j=int(x)+int(y);

算术运算符和算术表达式

算术运算符+  -  *  /  %  ++  --
关系运算符<  <=  ==  >  >=  !=
逻辑运算符!   &&    ||
位运算符<<        >>        ~         ^        &
赋值运算符=
条件运算符条件 ?  结果A :结果B (条件为真输出A,为假输出B)
逗号运算符
指针运算符* (取值)       &(取地址)
求字节数sizeof
强制类型转换(类型)
分量运算符.        ->
下标运算符[ ]
其他( )         -

C语言语句

控制语句:控制程序执行流程

if()~else条件语句
for()~循环语句
while()~循环语句
do~while()循环语句
continue继续语句
break间断语句
switch()开关语句
goto转向语句
return返回语句

C语言标准库函数:
(1)由编译系统提供的一系列函数,以库形式存放在系统中,不是C语言文本的组成部分

(2)库函数已编译成目标文件(.obj),在连接阶段才与源程序编译成的目标文件相连接,生成可执行文件

(3)调用形式:

函数名(参数表)

(4)在使用C语言函数库时,需要使用编译预处理命令

#include<相关头文件>

使相应的头文件包含到用户程序中

常用头文件:

stdio.h     定义输入输出函数
string.h    定义字符串操作函数
math.h      定义sin,cos等数学函数

标准输入输出函数

putchar    输出字符
getchar    输入字符
scanf      格式输入
printf     格式输出    格式:printf(格式控制,输出表列)

//格式控制:%[修饰符]格式字符,指定输出格式

puts       输出字符串
gets       输入字符串

格式字符表

d十进制整数
x, X十六进制无符号整数
o八进制无符号整数
u不带符号十进制整数
c单一字符
s字符串
e,E指数形式浮点小数
f小数形式浮点小数
g,Ge和f中较短的一种
%%百分号本身

scanf函数

scanf(格式控制,地址列表)

功能:按照指定格式从键盘读取数据,存入地址列表指定的存储单元中,并按回车键结束

地址列表:变量地址或字符串地址,地址间用逗号分割

强调:地址列表中每一项必须以取地址符&开头

#include <stdio.h>
void main(){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    printf("%d,%d,%d",a,b,c);
}

输入分隔符的指定:

(1)一般以空格,TAB,回车键作为分隔符

(2)输入数据时,遇非法输入则默认数据结束

(3)其他字符作为分隔符:格式串中两个格式符间有其他字符,则输入时,对应位置也要有相同字符

#include <stdio.h>
void main(){
    int a,b,c;
    scanf("%d:%d:%d",&a,&b,&c);//要输入3:4:5
    printf("%d,%d,%d",a,b,c);//3,4,5
}
#include <stdio.h>
#include <math.h>
void main(){
    int a,b,c,s,area;
    scanf("请输入三角形的三条边%d%d%d",&a,&b,&c);
    s=(a+b+c)*0.5;
    area=sqrt(s*(s-a)*(s-b)*(s-c));
    printf("三角形的面积是%d",area);
}

数组:

数组是一组相同类型变量的集合,在内存中存放在地址连续的存储单元中

特点

(1)数组中每个成员称为 “数组元素”,每个数组元素都有相同名称,但是用不同下标进行区分

(2)每个数组元素都可以当作单个变量来使用,但是数据类型必须相同

(3)数组类型可以是整形,实型,字符型,指针型,结构型

(4)数组根据其下标个数可以分为一维数组,二维数组以及多维数组

一维数组:

定义方式:数据类型   数组名[常量表达式]

数组名表示内存首地址,是地址常量

int data[5];
data[5]=10;
//注意C语言对数组不做越界检查,使用时要注意这一点

一位数组元素的引用:
(1)数组必须先定义,后使用

(2)只能逐个引用数组元素,不能一次引用整个数组

(3)数组元素表示形式:
        数组名 [下标]

下标可以是常量或者整型表达式

#include <stdio.h>
#include <math.h>
void main(){
    int s[5]={1,2,3,45,6};
    int ave;
    ave=s[0]+s[1]+s[2]+s[3]+s[4];
    ave=ave/10;
    printf("ave的值%d",ave);
}

二维数组:
定义:类型说明符        数组名 [常量表达式] [常量表达式]

int a [3][4];
float b [2][5];
int c[2][3][4]

字符数组:存放字符数据的数组

一维字符数组:存放一个字符串(每个数组元素存放一个字符)

二维字符数组:存放多个字符串(行数是字符串的个数)

字符数组的定义:
形式:

char 数组名 [常量表达式]

char 数组名 [常量表达式] [常量表达式]

常量表达式可以是整数,字符,符号常量

字符数组初始化

(1)逐个字符赋值

char ch[5]={'H','e','l','l','o'};

char ch[]={'H','e','l','l','o'}
#include <stdio.h>
#include <math.h>
void main(){
    char c[5]={'H','e','l','l','o'};
    int i;
    for(i=0;i<5;i++){
    printf("%c",c[i]);
    }
}

注意在输出时遇到\0就自动停止输出

字符串处理函数

(1)strlen函数

形式:strlen(str);

功能:计算并返回字符串长度(结束标记\0不计入其中)

说明:str可以时字符串常量,字符数组

#include <stdio.h>
#include <math.h>
void main(){
  int i=strlen("hauhzaiza");
  printf("字符串长度是%d",i);//9
}

(2)strcmp函数

形式:strcmp(str1,str2)

功能:比较两个字符串的大小,相同返回0,str1>str2,返回大于0,str1<str2返回小于0

比较规则:对两个字符串从左向右逐个字符比较ASCII码,直到遇到不同字符或者/0为止

(3) strcpy函数

形式:strcpy(str1,str2)

功能:将字符串str2的内容联通结束标记\0一起复制到str1中

说明:(1)str1和str2只能是字符数组

           (2)str1必须有足够的长度容纳str2的内容

           (3)不能使用赋值语句为一个字符数组赋值

(4) strcat函数

形式:strcat(str1,str2)

功能: 将字符串str1和str2首尾相接,拼接后,原str1串结尾的结束符\0被自动覆盖,新串的末尾自动加上\0,生成的新串存放于str1中

说明:

(1)str1必须是字符数组,str2可以是字符串常量或者字符数组

(2)str1必须有足够的长度容纳拼接后的新串的内容

C语言之函数

函数与库函数

函数:可反复使用的程序段,一个C语言源程序无论包含多少函数,整成情况下总是从main函数开始执行,从main函数结束

库函数:
C语言提供丰富的库函数,包括数学函数,字符和字符处理函数,输入输出函数等

待用C语言标准库函数要使用include命令

#include <XXX.h>
或者
#include "XXX.h"

函数定义格式:

函数类型  函数名(形参类型说明表)
{
说明部分
语句部分
}

(1)函数有函数头和函数体两部分组成,函数体有语句和其他分程序组成

(2)函数类型规定了函数返回值的数据类型,如无返回值,则数据类型为void,如果函数返回值,则在函数体中应有一条返回语句“return (表达式)”,没有返回值就是“return;”,也可以省略

(3)形参参数表示用逗号分割的若干个形式参数,每个形参可以是一个变量名,数组名,指针变量名和指针数组名,形参列表中每个参数的数据类型必须给出

预处理命令

ANSI C标准规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编程效率

这些预处理命令是ANSI C统一规定的,但是它本身不是C语言组成的一部分,不能直接对它们进行编译(因为编译程序不能识别它们)必须在对程序进行通常的编译之前,先对程序中的这些特殊明命令进行预处理

经过预处理后程序可由编译程序对预处理后的源程序进行通常的编译处理,得到可以执行的目标代码

C语言预处理功能主要有以下三种

(1)宏定义

(2)文件包含

(3)条件编译

为了与一般C语句相区别,这些命令符号以"#"开头

#define
#include

宏定义:

不带参数的宏定义

一般形式

#define  标识符  字符串

#define PI 3.2415926

宏定义的作用是在本程序文件中用指定的标识符PI来代替“3.1415926”这个字符串,在编译预处理时,将程序中在该命令以后出现的所有PI都用“3.1415926”代替,这种方法可以是用户用一个简单的名字代替长字符串

这里的标识符(名字)称为“宏名”

在预编译时将宏名替换成字符串的过程称为“宏展开”。 #define是宏定义命令

可以用#undef结束宏定义的有效范围

#include <stdio.h>
#include <math.h>
#define PI 3.14
void main(){
   float l,s,u,r;
   printf("input radius:");
   scanf("%f",&r);
   l=2*PI*r;
   s=PI*r*r;
 #undef PI //以下的PI就无效了,程序报错
   u=4.0/3*PI*r*r*r;
   printf("l=%10.4f\ns=%10.4f\nu=%10.4f\n",l,s,u);
}

在进行宏定义时,可以引用一定义的宏名,可以层层置换

#include <stdio.h>
#define R 3.0
#define PI 3.14
#define L 2*PI*R
#define S PI*R*R
void main( ){
   printf("L=%f\nS=%f\n",L,S);
}

带参数的宏定义:
作用:不是进行简单的字符串替换,还要进行参数替换

一般形式:#define  宏名(参数表)    字符串

字符串中包含在括弧中所指定的参数

#include <stdio.h>
#define S(a,b) a*b
void main(){
   area=S(2,3)
   //使用时用2代替a,3代替b,实际area就是3*2
}

对带实参的宏,则按照#define命令行中指定的字符串从左到右进行置换,若字符串中包含宏中的形参(如a,b),就将程序中相应的实参代替形参,如果宏定义中的字符串中的字符不是参数字符(比如a*b中的*),则保留,这样就形成了置换字符串

文件包含处理

功能:一个源文件可以将另一个源文件的内容全部包含进来

一般形式:

#include "文件名"
或者
#include <文件名>

处理过程:预编译时,用被包含文件的内容取代该预处理命令,再将“包含”后的文件作为一个源文件单位进行编译,得到目标文件.obj

条件编译:

所谓条件编译是对部分内容指定编译条件,使其只能在满足一定条件下才进行编译

条件编译命令的几种形式

#ifdef 标识符
//相当于ifdefine
程序段1
#else
程序段2
#endif
#ifndef 标识符
//相当于ifnodefine
程序段1
#else
程序段2
#endif
#if 表达式
程序段1
#else
程序段2
#endif

示例

#include <stdio.h>
#define LETTER 1
void main(){
   char str[20]="C Language",C;
   int i;
   i=0;
   while((C=str[i])!='\0'){
      i++;
      #if LETTER
      if(C>='a'&&C<='z')
      C=C-32;
      #else
      if(C>='A'&&C<='Z')
      C=C+32;
      #endif
      printf("%c",C);
   }
}

指针

地址和指针的概念

在程序中定义一个变量,在编译时就给这个变量分配一个内存单元,同时根据变量的类型决定这个内存单元的大小,比如整型2字节,实型4字节

内存中每一个字节都有一个编号,就是地址

对每一个变量,它在内存中都有一个存储位置这个位置就是该变量的地址,对变量值的存取是通过地址进行,在C语言中,这个地址称为“指针”

指针:一个变量的地址

指针变量:存放另一变量地址的变量

定义一个指针变量:指针变量在使用前必须定义,使其指向特定类型的变量,指针变量存放地址,必须定义为“指针类型”。

定义的一般形式: 基类型   *指针变量名

基类型:用来指定指针变量可以指向的变量的类型,将决定指针移动和运算时的移动量

构成:[存储类型]         数据类型

*:表示该变量为指针类型

int *p1,*p2;
//注意指针变量名是p1,p2,不是*p1,*p2
float *q;
static char *name;

理解&与*运算符

&:取地址运算符,含义是取变量的地址,单目运算符,优先级为2,结核性:自右向左

*:指针运算符(间接访问运算符),含义:取指针所指向变量的内容,单目运算符,优先级为2,结合性:自右向左

两者关系:互为逆运算

#include <stdio.h>
void main(){
   int i=10;
   int *ip;
   ip=&i;
   printf("%d %d %d",i,ip,*ip);
   //i=10;
   //ip=226832540;
   //*ip=10,就是取ip指向的地址的值
}
i_pointer指针变量,它的内容是地址量
*i_pointer指针的目标变量,它的内容是数据
&i_pointer指针变量占用内存的地址

指针变量初始化:

一般形式:[存储类型] 数据类型  *指针名=初始地址值

#include <stdio.h>
void main(){
   int i,j;
   int *p1,*p2;
   p1=&i;
   p2=&j;
   i=3;
   *p1=5;
   j=6;
   *p2=8;
   printf("i=%d,j=%d,*p1=%d,*p2=%d,p1=%d,p2=%d",i,j,*p1,*p2,p1,p2);
   //i=5,j=8,*p1=5,*p2=8,p1=192509676,p2=192509672
}

数组与指针:
数组的指针:数组的起始地址

数组元素的指针:指的是数组元素的地址

数组的地址->指针变量,指针变量就指向该数组了

引用数组元素:
(1)下标法:a[3]

(2)指针:用指针变量指向所找的数组元素,占内存少,运行速度快

指向数组元素的指针

int a[10];
int *p;
p=&a[0];
//或p=a;
//定义后赋值,两者等价

*p=1;
//表示对p当前指向的数组元素a[1]赋值为1

p+1指向同一数组的下一个元素a[2]
p的值(地址)加了2个字节,p+1=p+1xd(整型,d=2,实型,d=4,字符型d=1)指针变量所指数组元素的地址的计算与数据数据类型有关

定义指针变量时赋初值:

int *p=&a[0];
int *p=a;
设p=&a[0]
则
(1)p+i和a+i就是a[i]的地址a+ixd
(2)*(p+i)或*(a+i)是p+i或者a+i指向的数组元素a[i]
(3)指向数组的指针变量可带下标,p[i]与*(p+i)等价

结构体:
结构体:一种自定义的构造数据类型,把不同类型的数据组合成一个整体

struct [结构体名]
{
类型标识符    成员名;
类型标识符    成员名;

.........
}

//struct:关键字,不能省略
//[结构体名]:合法标识符,可以省略,省略就是无名结构体
//成员类型可以是基本型或构造型

示例:

struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}

声明结构体类型的同时定义结构体变量

struct 结构体名
{
类型标识符    成员名;
类型标识符    成员名;
.........
}变量名表列

示例:

struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}stu1,stu2;

//定义结构体的同时,定义了stu1和stu2两个变量,只有在定义了结构体变量后系统才会为其分配内存

说明:
(1)结构体类型与结构体变量概念不同

结构体类型不分配内存,不能赋值,存取和运算,而变量可以分配内存,赋值,存取和运算

(2)结构体中的成员可以单独使用,方法如普通变量;

(3)结构体可以嵌套

struct date
{
int month;
int day;
int year;
};

struct student
{
int num;
char  name[20];
struct date birthday;
}stu;

(4)结构体成员名与程序中变量名可以相同,两者不代表同一个对象

struct student
{
int num;
char name[20];
float sccore;
}stu;
//要使用就是stu.num

int num

结构体变量的引用

引用规则:
结构体变量不能整体引用,只能引用变量成员

结构体变量名.成员名

struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}stu1,stu2;

//引用语句
//stu.num=10;
//stu1.age++;
//stu1.score=85.5;
//stu1.score+=stu2.score;
#include <stdio.h>
 void main(){
struct student
{
   int No;
   float score;
}stu1,stu2;
scanf("%d,%f",&stu1.No,&stu1.score);
}

 结构体成员本身又是一个结构体类型,则需要找到最低一级的成员

struct student
{
int num;
char name[20];
struct date
{
int month;
int day;
int year;
}birthday;
}stu1,stu2;

//引用方式为stu1.birthday.month=12;

结构体变量初始化

方式1:

struct 结构体名
{
类型标识符    成员名1;
类型标识符    成员名2;
......
};
struct 结构体名 结构体变量={初始数据};

示例

struct stu
{
int num;
char name[20];
int age;
char addr[30];
};
struct stu a={112,"ajsioq",19,"200北京路"}

方式2:

struct 结构体名
{
类型标识符    成员名1;
类型标识符    成员名2;
......
}结构体变量={初始数据}

示例

struct student
{
int num;
char name[20];
int age;
char addr[30];
}a={112,"WL",19,"222 Beijing Road"};

结构体数组:
具有相同结构的结构体也可以成为数组

定义结构体数组

方式1:间接定义

struct student
{
int num;
char name[20];
char sex;
int age;
};
struct student stu[2];
//定义了2个成员,每个成员都包含num,name,sex,age

共用体

共用体概念:构造数据的类型,也叫做联合体,用于使几个不同类型的变量攻占一段内存(相互覆盖)

类型定义形式:

union    共用体名
{
类型标识符    成员名;
类型标识符    成员名;
......
};
union data
{
int i;
char ch;
float f;
}

结构体对每一个变量成员单独分配内存,共用体只分配一块内存

共用体变量的定义:

形式1

union data{
int i;
char ch;
float f;
}a,b;

形式2

union data
{
int i;
char ch;
float f;
};
union data a,b,c,*p,d[3];

形式3

union
{
int i;
char ch;
float f;
}a,b,c;

注意:共用体变量在任何时刻都只有一个成员存在,共用体变量定义分配内存,长度=最长成员所占字节数

共用体变量的引用方式:
3种等价方式:

共用体变量名.成员名

共用体指针名->成员名

(*共用体指针名).成员名

union data
{
int i;
char ch;
float f;
};
union data a,b,c,*p,d[3];

//引用方式
a.i    a.ch    a.f;
p->i    p->ch    p->f;
(*p).i    (*p).ch    (*p).f
d[0].i    d[0].ch    d[0].f

引用规则:不能引用共用体变量,只能引用其成员

共用体数据类型的特点

(1)同一内存段可以用来存放几种不同类型的成员,但每一瞬间只能存放其中一种,而不是同时存放几种

(2)共用体变量中起作用的成员是最后一次存放的成员

a.i=1;
a.ch='a';
a.f=1.5;
printf("%d",a.i)//这句可以编译通过,但是结果不对
printf("%f",a.f)//结果正确

(3)共用体变量和它的各个成员的地址都是同一地址

枚举类型:

枚举类型是ANSI C新标准所增加的

如果一个变量只有几种可能的值,可以定义为枚举类型,枚举是将变量的值一亿列举出来,变量的值只限于列举出来的值的范围内

枚举类型及其变量的定义形式:
enum        枚举类型名 {枚举元素列表}        枚举元素变量列表

可以先声明类型在定义变量,或者同时进行或直接定义变量

enum weekday
{sun,mom,tue,wed,thhu,fri,sat};
enum weekday workday,week_end;//声明2个变量
enum weekday
{sun,mon,tue,wed,thu,fri,sat} workday,week_end;

说明:

(1)在编译中,对枚举元素按照常量处理,它们不是变量,不能直接赋值

(2)枚举元素作为常量,它们是有值的,语言编译按定义时的顺序使它们的值为0,1,2...

typedef定义类型功能:用自定义的名字为已有数据类型命名

类型定义简单形式:
typedef type name

说明:

(1)typedef没有创造新数据类型

(2)typedef定义类型,不能定义变量

(3)typedef与define不同

define是预编译时,简单的字符置换,typedef是编译时处理为已有类型命名

typedef定义类型步骤

(1) 按定义变量方法写出定体,比如 int i;

(2) 将变量名换成新类型名, 如 INTEGER

(3) 最前面加typedef        如typedef int INTEGER

(4) 用新类型定义变量        如INTEGER i,j;

示例:

定义数组类型

int a[100];
int ARRAY[100];
typedef int ARRAY[100];//等价于int a[100],b[100],c[100];
ARRAY a,b

定义函数指针类型

int (*p)();
int (*POWER)();
typedef int (*POWER)();
POWER p1,p2;

定义结构体类型

typedef struct date
{
int month;
int day;
int year;
}DATE;

DATE birthday,*p;

类型定义可嵌套

typedef struct club
{
char name[20];
int size;
int year;
}GROUP;

typedef GROUP *PG;
PG pclub

文件

文件概述:

文件:存储在外部介质上上数据的集合,是操作系统数据管理的单位

文件分类:

按照文件逻辑结构:

记录文件:由具有一定结构的记录组成(定长和不定长)

流式文件:由一个个字符(字节)数据顺序组成

按存储介质分:

普通文件:存储介质文件(磁盘,磁带)

设备文件:非存储介质(键盘,显示器,打印机)

按照数据组织形式:

文本文件:ASCII文件,每个字节存放一个字符的ASCII码

二进制文件:数据按其在内存中的存储形式原样存放

文件处理方法:

缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟内存缓冲区,可以减少主机和外部设备频繁交换数据的次数

非缓冲文件系统:低级文件系统,由用户在程序中为每个文件设定缓冲区

文件类型指针:

文件结构体类型FILE

typedef struct
{
short level;
unsigned flags;
char fd;
unsigned char hold;
short bsize;
unsigned char *buffer;
unsigned ar *crup;
unsigned istemp;
short token;
}FILE

文件的打开与关闭

C文件操作用库函数实现,包含在stdio.h

文件使用方式:打开文件->文件读写->关闭文件

系统自动打开和关闭3个标准文件

标准输入——键盘        stdin

标准输出——显示器        stdout

标准出错输出——显示器        stderr

文件的打开(fopen函数)

函数原型:

FILE *fopen(char *name, char *mode)

调用方式:fopen("文件名","使用文件方式")

示例

FILE *fp
fp=fopen("文件路径","r")

正常打开,返会文件结构体指针,打开失败就返回NULL

文件的关闭:

作用:是文件指针变量与文件“脱钩”,释放文件结构体和文件指针

示例:

FILE *fp;
fp=fopen("a.txt","r");
fclose(fp);

返回值:用于表示文件为是否被正确地关闭,如果文件顺利关闭,该值为0,否则为-1(EOF),返回值可以用ferror函数测试

文件的读写

文件打开之后,就可以进行读写操作

读写文件的一个字符

fputc函数(putc)

函数原型: int fputc(int c, FILE *fp)

功能:把亿字节代码c写入fp指向的文件中

返回值:正常返回c,出错返回EOF(-1)

数据块输入输出函数:fread和fwrite

一般调用形式:

fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
//buffer:要读入的数据块的存放首地址或要输出的数据块的起始地址
//size:每个要读/写的数据块的大小(字节数)
//count:要读写的数据块的个数
//fp:要读写的文件指针
返回值:成功就返回count的值,出错或者文件尾,0值
fread/fwrite一般用于二进制文件的输入输出,若文件以二进制形式打开,用fread或fwrite可读写任何类型的数据,如fread(f,4,2,fp)

按指定格式读写文件的函数:fprintf和fscanf

一般调用格式

fscanf(fp,格式字符串,输入列表)
fprintf(fp,格式字符串,输出列表);
//返回值:成功就返回I/O的个数,出错或文件尾,返回EOF
//由于输入输出时要进行ASCII码和二进制形式的转换,费时较多
fscanf(fp,"%d,%f",&i,&t);
fprintf(fp,"%d,%6.2f",i,t);

putw函数和getw函数

作用:以二进制i形式,对磁盘文件读写一个int型整数,2个字节

返回值:成功就返回所写的整数值,失败返回EOF

putw(10,fp);
i=getw(fp);

fgets和fputs函数

形式:

fgets(str,n,fp);
//str:字符数组,n-1个字符
fputs(字符串,fp);("\0"不输出)
返回值:
fgets正常时返回字符串首地址,出错或者文件尾,NULL
fputs正常时返回写入的最后一个字符,出错为EOF

文件的定位:

文件位置指针——指向当前读写位置之的指针,具体位置由文件打开方式确定

"r","w"指向文件头
"a"指向文件尾

读写方式:

顺序读写:位置指针按照字节位置顺序移动

随机读写:位置指针按需移动到任意位置

fseek函数和随机读写

调用形式:

fseek(文件类型指针,位移量,起始点);
//功能:改变文件位置指针的位置
//返回值:成功返回0,失败返回非0值

ftell函数

函数原型:

long ftell(FILE *fp)

功能:得到流式文件中位置指针的当前位置(用相对于文件开头的位移量表示)

返回值:返回当前位置指针位置,失败就返回-1L

出错的检测:

ferror函数:检测文件是否出现错误

调用形式:ferror(fp);

返回值:未出错就返回0,出错就返回非0值

fopen打开文件时,ferror函数初始值自动置为0;

clearerr函数:

调用形式:clearerr(fp)

功能:是文件错误标志位置为0,无返回值

说明:出错后,错误标志一直保留,直到对同一文件调clearerr(fp)或rewind或任何其他一个输入输出函数

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值