第一讲 预处理命令
1、预处理指令的概念
用 “#” 开头的一些特殊的指令 作用:在编译之前做些处理主要包括宏定义、“文件包含”(include)、条件编译
2、宏定义
宏:特殊的标示符,宏不是语句,不需要分号结束宏替换,在编译之前,在源文件中,所有出现宏名的地方都用 宏代表的字符串去替换
注意:当宏出现在字符串中的时候,宏不会进行替换
1)无参宏
#define 宏名 宏代表的字符串
#define M 10
#define AREA 3.14*M*M
#define PI 3.14
2)有参宏
#define Mi(y) y*y+3*y
()中的y是形参,宏中的形参在定义的不会分配空间,不需要写类型
#define MAX(a,b) a>b?a:b
#define SUM(a,b) a+b 3)#define和typedef的区别
注意用宏定义表示数据类型和用typedef定义数据说明符的区别。宏定义只是简单的字符串代换, 是在预处理完成的,而typedef是在编译时 处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。
2、include文件包含
#include " " 包含的是一个用户定义的文件,可以是头文件,也可是普通文件1)在当前文件所在的路径下查找
2)如果上面没有找,到编译器include路径查找
3)如果编译器include路径下没有找到,系统的include路径下查找
4)如果上面三个都没有找到就报错了。
#include <> 包含一个系统(编译器自带)的头文件
1)编译器的include路径下查找
2)如果没有找到就系统include路径下查找
3)如果都没有找到就报错 注意:1)include 可以包含头文件,也可以包含文本文件。不一定非在第一行 2)一个#include命令只能指定一个被包含文件,如果要包含n个,要用n个#include命令 3)文件包含可以嵌套,在一个被包含文件中又可以包含另一个被包含文件
3、条件编译
当条件满足的时候再去编译一段代码好处:可移植、生成更小的目标文件
条件编译三种形式:
1)#if-#else 条件编译指令
第一种形式的格式为:
#if 常量表达式
程序段1
#else
程序段2
#endif
它的功能是,如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。
2)#ifdef 条件编译指令
第二种形式的格式为:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的功能是,如果标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的 #else可以没有,即可以写为:
#ifdef 标识符
程序段
#endif
3)#ifndef 条件编译指令 第三种形式的格式为:
#ifndef 标识符
程序段1
#else
程序段2
#endif
它的功能与第二种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2 进行编译。这与第二种形式的功能正相反。
第二讲 文件操作
1、文件的基本概念
存储外部介质上得数据集,数据集有一个名称就是文件名2、文件的分类:
1)用户角度:普通文件和设备文件2)存储的内容:
ascii文件(文本文件) :
存储的流程:根据文本找到其对应的ascii码值---->转为二进制-->写到文件中
读取流程: 二进制-->10进制-->找对应的字符-->显示出来
二进制文件:二进制数据的存取
3、文件的操作流程:
1)导入头文件 stdio.h2) 定义文件指针
3)打开文件
4)操作文件
5)关闭文件
4、文件指针
FILE 结构体FILE *fp; 结构体指针
作用:存储一个文件的首地址,指向一个文件
5、文件的打开和关闭
打开 fopen(文件名,操作方式);fopen("a.txt","r"); //a.txt默认的去products目录去找
fopen("/Users/apple/Desktop/a.txt","r");
操作方式:
r w a b + t
读 写 追加 二级制 读写 文本
w -- 写入文件的时候,如果文件不存在,则创建,若存在,则覆盖
r+ w+ wb+ a+
关闭文件:
fclose(文件指针);
6、文件操作的函数
1) 字符型数据的读取和写入写入:
fputc('字符',文件指针);
char c='A';
fputc(c,fp);
读取:
char ch = fgetc(fp);
2)字符串类型数据的读取和写入
写入:
fputs(数组名/指针名,fp); //fputs(数组名,stdout);
读取:
fgets(数组名/指针名,长度,fp);
fgets实际读取的字符个数是长度-1,遇到\n 结束,遇到EOF也会结束
3)数据块的读取和写入
写入:
fwrite(写入的变量地址,数据块的大小,块数,fp);
int a =123;
fwrite(&a,sizeof(int),1,fp);
struct Student stu1;
fwrite(&stu1,sizeof(struct Student),1,fp);
读取:
struct Student s1;
fread(变量的地址,数据块的大小,块数,fp)
fread(&s1,sizeof(struct Student),1,fp);
//使用s1进行输出
4)格式化的读取和写入
写入数据和读取数据按照一定的格式进行
写入:
fprintf(文件指针,"格式化的字符串",变量列表);
fprintf(fp,"%d,%c,%d#",10,'a',20);
10,a,20#10,a,20#10,a,20#
读取:
fscanf(fp,"%d,%c,%d#",&a,&ch,&b);
fprintf(fp,"%d,%s,%d",20,"abc",30);
fscanf(fp,"%d,%s,%d",&a,str,&b);
str = abc,30
改成:
fprintf(fp,"%d,%d,%s",20,20,"abc");
fscanf(fp,"%d,%d,%s",&a,&b,str);
fscanf(fp,"%d,%d,%s",&a,&b,str);
5)文件的随机读取
设定文件的头指针的位置
默认fp是指向文件的首地址
A rewind(fp); //fp指向首地址
B fseek(fp,偏移的距离,起始点);
fseek(fp,32L,SEEK_SET); //从文件头部开始,偏移32个字节
6)文件的检测函数
feof() 用来检测文件是否到了末尾
如果没有到末尾 0,到末尾 1
缺点:多执行一次
7、文件操作几个应用
应用一:键盘输入一行字符,写入一个文件再把该文件内容读出显示在屏幕上#include<stdio.h>应用二:从键盘输入两个学生数据,写入一个文件中,再读出这两个学生的数据显示在屏幕上。
int main(int argc, const char * argv[]) {
//定义文件指针
FILE *fp =fopen("a.txt", "w+");
char ch;
if (fp!=NULL) {
//文件打开成功
int count=0;
//先预读取一个字符
ch = getchar();
//如果不等于\n表示输入没有结束
while (ch!='\n') {
count++;
//写入字符到文件中
fputc(ch, fp);
//再次读取下一个字符
ch = getchar();
}
printf("本次共写入:%d个字符\n",count);
//让fp指针重新指向文件头部
rewind(fp);
//文件打开成功
ch = fgetc(fp);
count=0;
//EOF表示文件末尾,其值为 -1
while (ch!=EOF) {
count++;
putchar(ch);
ch = fgetc(fp);//每次读取一个字符
}
printf("\n读取总字符个数%d\n",count);
}else{
//文件打开失败
printf("文件读取失败!按任意键退出~");
getchar(); //等待用户输入一个字符后,再退出
exit(1); //程序退出
}
fclose(fp);
return 0;
}
#include<stdio.h>
struct Student {
char name[20];
int sno;
int age;
float score;
};
int main(int argc, const char * argv[]) {
struct Student stu[2]={{"def",1,18,66.0f},{"abc",2,23,78.0f}};
struct Student stu2[2];
FILE *fp = fopen("student.data", "wb+");
if (fp!=NULL) {
//写入信息到文件中
for(int i=0;i<2;i++){
printf("学号: %d,姓名: %s,年龄:%d,分数: %.2f\n",stu[i].sno,stu[i].name,stu[i].age,stu[i].score);
fwrite(&stu[i],1 , sizeof(struct Student), fp);
}
printf("写入完成!\n");
//移动指针到文件头部
rewind(fp);
for (int i=0; i<2; i++) {
fread(&stu2[i], 1, sizeof(struct Student), fp);
printf("学号: %d,姓名: %s,年龄:%d,分数: %.2f\n",stu2[i].sno,stu2[i].name,stu2[i].age,stu2[i].score);
}
}
fclose(fp);
return 0;
}