黑马程序员------C语言基础 预处理指令、文件操作及其他
2015-07-25 22:41
495 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
预处理指令、文件操作及其他
以"#"号开头的预处理指令,如命令#include,宏定义命令#define等。在源程序中这么命令都放在函数之外,而且都放在源文件前面,他们称为预处理部分
所谓预处理是指在进行编译的第一遍(词法扫描和语法分析)之前的工作。
x 语言多种预处理指令功能:宏定义、文件包含、条件编译
.o .out
源程序->预处理(宏替换)-> 编译 -> 链接-> 执行程序
一、预处理指令
1、宏定义
宏:在c语言中我们自定义的标示符,习惯大写
#include 宏名 宏字符串 (可以是常量、变量、表达式)
注意:预处理指令,经常写在函数之前
宏替换:源程序在编译之前,由预处理程序对我们写的源代码进行处理:会把源代码中所出现 宏名 的地方一律使用 宏的字符串 去替换
宏使用的注意事项:
1.宏是有作用域的 #undef 宏名 可以取消宏定义
#include R 4
int a= R
#define R M 这里取消宏定义,下面的代码用不了宏了
2.在字符串中出现的宏名不会被替换
3.宏定义可以嵌套使用
#define R 4
#define PI 3.14
#define AREA PI*R*R //嵌套定义
4,使用宏起别名
#include INT1 int
这样就可以 这么定义整型
INT1 a=10;
5.有参数宏和无参数宏
无参数宏 #include M 10
有参数宏 #define SUM(a) a+a
有参数宏的使用注意事项:
宏的形参之间可以出现空格 ,但是宏名和形参之间不能空格
有参数宏 宏的参数最好用括号括起来
应用使用有参宏求最大值
#include <stdio.h>
//定义一个有参宏 求两个数的最大值
#define MAX(a,b) a>b?a:b
int main(int argc, const char * argv[]) {
// 调用宏
int c =MAX(3, 4);
printf("最大值是%d",c);
return 0;
}
6 typedef 和#include 的区别
当 #include INT1 int
typedef int INT2;
这里 INT1 a,b a,b都是定义的整型变量
INT2 a,b 也一样是整型变量
定义指针时
#include INT3 int*
typedef int* INT4 ;
INT1 f1,f2 =NULL; 这里f1 是zhiz 而f2只是个整型变量 说明宏的定义知识单纯的文本复制的替换
INT4 f1,f2 = NULL; 这里 f1,f2 都是指针。
2.条件编译指令
1. #if -#elseif
条件编译 :
发生在预处理阶段 ,在编译之前做的事情
核心:根据条件编译指定的代码
条件不同,编译的部分也不同,生成的目标文件(.o)大小也不一样
传统方式
int score =76;
判断成句属于哪个成绩
if(score<60){
printf("E\n");
}else if(score<= 69){
printf("d\n");
}else if(score<= 79){
printf("c\n");
}else if(score<= 89){
printf("b\n");
}else {
printf("A\n")
}
#if score <60
printf("E\n");
#elif scoe <=69
printf("d\n");
#elif scoe <=79
printf("c\n");
#elif scoe <=89
printf("b\n");
#else
printf("a\n");
#endif
这里只选择一个符合要求的score 进行一段代码的预编译
2.#ifdef 有来判断某个宏是否定义
#include DEBUG1 1
int a=0;
#ifdef DEBUG1 DEBUG1为1是执行 a=10 ;
a=10; 否则执行 a=100;
#else
a=100;
#endif
3.使用条件编译指令调试bug
#if DEBUG1 ==1 1或0 1显示调试信息 0不显示调试信息
//显示调试信息
#define Log(format,....)printf(format,##__VA_ARGS__);
#else
#define Log(format,.......)
//不显示调试信息
#endif
二、文件操作
1。文件概念
文件; 指存储在外部介质上数据的集合,这个数据有一个名称,叫做文件名
文件的分类 从用户角度 文件分为普通文件和设备文件
从文件编码 文件分ascii码文件和二进制文件
文件操作的步骤
1)引入头文件<stdio.h>
2)定义文件指针
3)打开文件
4)文件读写
5)关闭文件
对文件读和写是最常用的文件操作,在c语言中提供了多种文件读写的函数
字符读写函数 fgetc和fputc
读写字符串函数 fgets和fputs
数据快读写函数 fread 和fwrite
格式化读写 fscanf 和fprintf
c语言文件指针
在c语言中用一个指针变量指向一个文件,这个指针称为文件指针
文件指针
FILE *指针变量表示符;
2。文件的打开和关闭函数
文件操作步骤
1)引入头文件 stdio.h
2)建立文件指针 FILE *fp =NULL;
3)打开文件 fopen(文件名,操作方式);
如果文件打开成功返回文件收地址,失败返回NULL
4)操作文件
5)关闭文件 fclose(文件指针);
3文件使用的方式及注意事项
文件使用方式
4字符读写函数 fgetc和putc
字符读写函数是以字符(字节)为单位的读写函数。每次可以从文件读出或向文件写入一个字符
fputc() 写入一个字符到文件中
假设把 ch写到 fputc1.txt 文件中
char ch ='x''
int count = 0; while (ch!='\n') { count++; fputc(ch, fp);//把字符保存到文件中 ch = getchar();//获取下一个字符串 } printf("本次一共写入了%d个字符\n",count); printf("1----------\n"); rewind(fp);//作用是把问价指针,重新指向文件首地址 int k = 0; //从文件中读取一个字符 ch = fgetc(fp); while (ch!=EOF) { k++; //显示到控制台
putchar(ch); //读取一个字符 ch =fgetc(fp); } printf("本次共输出了%d个字符\n",k); } fclose(fp); //关闭读取文件 return 0; }
6.数据快的读写函数fread 和fwrite
一般形式fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
buffer时指针用来存放数据输入的首地址 表示存放数据输出的首地址
size 表示数据块字节数
count 表示要读写的数据块块数
fp 表示文件指针
7.格式化读写函数 fscanf和 fprintf
两个函数调用的格式
fscanf(文件指针,格式字符串,输入列表);
fprintf(文件zhiz,格式化字符串,输出列表);
列如要求 把数据照这个样格式
0#1;
1#2;
2#3;
8.读取和写入一个二维数组
9文件的随机读写实现
fseek(文件zhiz,位移量 ,起始点);
位移量 表示移动的字节数,要求位移量是long类型数据,要求加后缀“L”
起始点 表示从何处开始计算位移量,规定的起始点有三种,文件首,当前位置和文件尾。
文件首 SEEK_SET 0
当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
只输出第二个人的信息
10.文件结束检函数feof
feof(fp)也就是找文件结束的标志。
读写出错函数 ferror (文件指针);
能检查文件在输入输出时读写是否出错 如果ferror返回的时0就表示没有出错,否则表示文件有错。
文件出错标志和文件结束标志函数
clearerr(文件指针) 用于清除错误标志和文件结束标志,使他们为0值
预处理指令、文件操作及其他
以"#"号开头的预处理指令,如命令#include,宏定义命令#define等。在源程序中这么命令都放在函数之外,而且都放在源文件前面,他们称为预处理部分
所谓预处理是指在进行编译的第一遍(词法扫描和语法分析)之前的工作。
x 语言多种预处理指令功能:宏定义、文件包含、条件编译
.o .out
源程序->预处理(宏替换)-> 编译 -> 链接-> 执行程序
一、预处理指令
1、宏定义
宏:在c语言中我们自定义的标示符,习惯大写
#include 宏名 宏字符串 (可以是常量、变量、表达式)
注意:预处理指令,经常写在函数之前
宏替换:源程序在编译之前,由预处理程序对我们写的源代码进行处理:会把源代码中所出现 宏名 的地方一律使用 宏的字符串 去替换
宏使用的注意事项:
1.宏是有作用域的 #undef 宏名 可以取消宏定义
#include R 4
int a= R
#define R M 这里取消宏定义,下面的代码用不了宏了
2.在字符串中出现的宏名不会被替换
3.宏定义可以嵌套使用
#define R 4
#define PI 3.14
#define AREA PI*R*R //嵌套定义
4,使用宏起别名
#include INT1 int
这样就可以 这么定义整型
INT1 a=10;
5.有参数宏和无参数宏
无参数宏 #include M 10
有参数宏 #define SUM(a) a+a
有参数宏的使用注意事项:
宏的形参之间可以出现空格 ,但是宏名和形参之间不能空格
有参数宏 宏的参数最好用括号括起来
应用使用有参宏求最大值
#include <stdio.h>
//定义一个有参宏 求两个数的最大值
#define MAX(a,b) a>b?a:b
int main(int argc, const char * argv[]) {
// 调用宏
int c =MAX(3, 4);
printf("最大值是%d",c);
return 0;
}
6 typedef 和#include 的区别
当 #include INT1 int
typedef int INT2;
这里 INT1 a,b a,b都是定义的整型变量
INT2 a,b 也一样是整型变量
定义指针时
#include INT3 int*
typedef int* INT4 ;
INT1 f1,f2 =NULL; 这里f1 是zhiz 而f2只是个整型变量 说明宏的定义知识单纯的文本复制的替换
INT4 f1,f2 = NULL; 这里 f1,f2 都是指针。
2.条件编译指令
1. #if -#elseif
条件编译 :
发生在预处理阶段 ,在编译之前做的事情
核心:根据条件编译指定的代码
条件不同,编译的部分也不同,生成的目标文件(.o)大小也不一样
传统方式
int score =76;
判断成句属于哪个成绩
if(score<60){
printf("E\n");
}else if(score<= 69){
printf("d\n");
}else if(score<= 79){
printf("c\n");
}else if(score<= 89){
printf("b\n");
}else {
printf("A\n")
}
#if score <60
printf("E\n");
#elif scoe <=69
printf("d\n");
#elif scoe <=79
printf("c\n");
#elif scoe <=89
printf("b\n");
#else
printf("a\n");
#endif
这里只选择一个符合要求的score 进行一段代码的预编译
2.#ifdef 有来判断某个宏是否定义
#include DEBUG1 1
int a=0;
#ifdef DEBUG1 DEBUG1为1是执行 a=10 ;
a=10; 否则执行 a=100;
#else
a=100;
#endif
3.使用条件编译指令调试bug
#if DEBUG1 ==1 1或0 1显示调试信息 0不显示调试信息
//显示调试信息
#define Log(format,....)printf(format,##__VA_ARGS__);
#else
#define Log(format,.......)
//不显示调试信息
#endif
二、文件操作
1。文件概念
文件; 指存储在外部介质上数据的集合,这个数据有一个名称,叫做文件名
文件的分类 从用户角度 文件分为普通文件和设备文件
从文件编码 文件分ascii码文件和二进制文件
文件操作的步骤
1)引入头文件<stdio.h>
2)定义文件指针
3)打开文件
4)文件读写
5)关闭文件
对文件读和写是最常用的文件操作,在c语言中提供了多种文件读写的函数
字符读写函数 fgetc和fputc
读写字符串函数 fgets和fputs
数据快读写函数 fread 和fwrite
格式化读写 fscanf 和fprintf
c语言文件指针
在c语言中用一个指针变量指向一个文件,这个指针称为文件指针
文件指针
FILE *指针变量表示符;
2。文件的打开和关闭函数
文件操作步骤
1)引入头文件 stdio.h
2)建立文件指针 FILE *fp =NULL;
3)打开文件 fopen(文件名,操作方式);
如果文件打开成功返回文件收地址,失败返回NULL
4)操作文件
5)关闭文件 fclose(文件指针);
#include <stdio.h> int main(int argc, const char * argv[]) { //定义文件指针 FILE *fp =NULL; //打开文件 是文件操作方式 fp =fopen("a.txt", "r"); //fopen成功,返回的是文件首地址 //fopen失败 返回NULL if(fp!=NULL){ //文件操作 printf("文件打开成功\n"); }else{ //给用户提示 printf("文件打开失败,请任意键退出\n"); //按任意键推出 getchar();//要求从键盘接受一个字符 //退出 exit(1);//非正常退出 } //文件关闭 fclose(fp); return 0; }
3文件使用的方式及注意事项
文件使用方式
4字符读写函数 fgetc和putc
字符读写函数是以字符(字节)为单位的读写函数。每次可以从文件读出或向文件写入一个字符
fputc() 写入一个字符到文件中
假设把 ch写到 fputc1.txt 文件中
char ch ='x''
#include <stdio.h> void test(){ char ch ='x'; //打开文件 打开fputc1.txt 以w方式(写,如果文件不存在可创建) FILE *fp=fopen("fputc1.txt", "w"); //判断文件是否打开成功 if (fp != NULL) { //将ch 要写入的字符 文件指针 //写到fput1.txt文件中 fputc(ch,fp); printf("写入成功\n"); } //关闭文件 fclose(fp); } int main(int argc, const char * argv[]) { FILE *fp=fopen("fputc1.txt", "r"); //判断文件是否打开成功 c = fgetc(fp); if (fp != NULL) { //字符文件要读取到的位置 c 文件指针 //写到fput1.txt文件中 printf("%c\n",c); printf("文件打开成功\n"); } //关闭文件 fclose(fp); return 0; } 使用 fgetc 和fputc 读取和写入字符串 #include <stdio.h> #include <string.h> int main(int argc, const char * argv[]) { //定义文件指针,打开文件 futcString.txt 以w写入 FILE *fp=fopen("fputcString.txt","r"); if(fp!=NULL){ // char ch[]="i love china"; // for(int i=0;i <strlen(ch);i++){ // fputc(ch[i], fp); // printf("文件写入成功]\n"); // } // char s =fgetc(fp); //EOF是文件的末尾的标志 //s ==EOF 可以理解为,已经读取到文件的最后了 while (s!=EOF) { putchar(s);//输出字符 s = fgetc(fp);//又从文件中读取下一个字符。这里fgetc 会自动转换指针指向下一个字符。 } } fclose(fp); return 0; } 保存键盘输入的字符串 #include <stdio.h> int main(int argc, const char * argv[]) { FILE *fp =fopen("string1.txt","w+"); if (fp!=NULL) { printf("请输入一个字符串\n"); char ch; ch = getchar(); <pre class="csharp" name="code">5.字符串读写函数 fgets 和fputs #include <stdio.h> int main(int argc, const char * argv[]) { //把字符串写入到文件中去 char str[]="welcome to yilake"; FILE *fp = fopen("fputsstring.txt", "w+"); if (fp!=NULL) { int count =0; // 写入字符串到文件中 ,count 返回读取的字符数 count = fputs(str,fp ); printf("写入成功,本次写入%d个字节]\n",count); rewind(fp); char str1[20]; //从文件中读取字符到字符数组str1中 // 数组名 长度 文件指针 fgets(str1, sizeof(str1),fp); // fgets读取的时候,当文件读取完会自动的给字符后面加'\0' //fgets读取的时候,遇到\n或者EOF ,读取完毕 printf("输入的字符串是%s",str1); } //关闭文件指针 fclose(fp); return 0; }
int count = 0; while (ch!='\n') { count++; fputc(ch, fp);//把字符保存到文件中 ch = getchar();//获取下一个字符串 } printf("本次一共写入了%d个字符\n",count); printf("1----------\n"); rewind(fp);//作用是把问价指针,重新指向文件首地址 int k = 0; //从文件中读取一个字符 ch = fgetc(fp); while (ch!=EOF) { k++; //显示到控制台
putchar(ch); //读取一个字符 ch =fgetc(fp); } printf("本次共输出了%d个字符\n",k); } fclose(fp); //关闭读取文件 return 0; }
6.数据快的读写函数fread 和fwrite
一般形式fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
buffer时指针用来存放数据输入的首地址 表示存放数据输出的首地址
size 表示数据块字节数
count 表示要读写的数据块块数
fp 表示文件指针
#include <stdio.h> #include <string.h> int main(int argc, const char * argv[]) { //fwrite 写一个数据块 //先写一个字符串 FILE *fp =fopen("fwrite.txt", "w+"); if (fp!=NULL) { // 写文件 char *str ="helloworld!"; //fwrite(地址,块大小,数据,文件指针); fwrite(str,strlen(str),1,fp); printf("文件写入成功\n"); rewind(fp); char str1[12]; //读出一个到字符数组str1中 fread(str1, sizeof(str1), 1, fp); printf("%s",str1); } fclose(fp); return 0; } 应用读写结构体 #include <stdio.h> struct Student{ char name[21]; int age; float score; }; int main(int argc, const char * argv[]) { struct Student stu[2]={{"李白",18,88.88f},{"杜甫",23,99.99f}}; FILE *fp =fopen("studentScore.data","wb+"); if (fp!=NULL) { for (int i=0; i<2; i++) { //从文件中读取一个元素(32)到stu中去 //每次都写入一个元素 fwrite(&stu[i], sizeof(struct Student), 1,fp); } printf("写入成功\n"); printf("————————————————— ii\n"); rewind(fp); struct Student stu1[2]; //从文件循环读取 for (int i=0; i<2; i++) { //从文件中读取一个元素(32)到stu中去 fread(&stu1[i], sizeof(struct Student), 1,fp); } //查看读取数据 for (int i = 0; i<2; i++) { printf("姓名%s 年龄%d 成绩%.2f\n",stu1[i].name,stu1[i].age,stu1[i].score); } } fclose(fp); return 0; }
7.格式化读写函数 fscanf和 fprintf
两个函数调用的格式
fscanf(文件指针,格式字符串,输入列表);
fprintf(文件zhiz,格式化字符串,输出列表);
列如要求 把数据照这个样格式
0#1;
1#2;
2#3;
#include <stdio.h> int main(int argc, const char * argv[]) { FILE *fp =fopen("fprintf.txt", "w+"); if (fp!=NULL) { int a= 3,b=4; fprintf(fp,"%d#%d;",a,b ); printf("写入成功\n"); rewind(fp);//指针回到文件首地址 int m=0,n=0; //从文件中读取数据到变量中 fscanf(fp, "%d#%d;",&m,&n); printf("%d,%d",m,n); } fclose(fp); return 0; }
8.读取和写入一个二维数组
#include <stdio.h> int main(int argc, const char * argv[]) { int a[3][2]={1,2,3,4,5,6}; FILE *fp =fopen("arr.txt", "w+"); if (fp!=NULL) { for (int i=0; i<3; i++) { fprintf(fp, "%d,%d#", a[i][0],a[i][1]); } printf("写入成功\n"); rewind(fp); int c[3][2]; for (int i=0; i < 3; i++) { fscanf(fp, "%d,%d#",&c[i][0],&c[i][1]); } for (int i=0; i<3; i++) { for (int j=0; j <2 ;j++ ) { printf("%d\t",c[i][j]); } } } fclose(fp); return 0; }
9文件的随机读写实现
fseek(文件zhiz,位移量 ,起始点);
位移量 表示移动的字节数,要求位移量是long类型数据,要求加后缀“L”
起始点 表示从何处开始计算位移量,规定的起始点有三种,文件首,当前位置和文件尾。
文件首 SEEK_SET 0
当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
只输出第二个人的信息
#include <stdio.h> struct Student{ char*name; int age; float score; }; int main(int argc, const char * argv[]) { struct Student gril[3]={{"zsf",18,34.55f},{"lzl",23,88.88f},{"lzz",22,99.99f}}; FILE *fp =fopen("student.data", "w+"); if (fp!=NULL) { for (int i =0; i<3; i++) { fwrite(&gril[i], sizeof(struct Student), 1, fp); } printf("写入成功\n"); rewind(fp); // 移动的字节数 起始点 struct Student gril1; // 文件定位 从起始点开始移动(32个字节) fseek(fp, sizeof(struct Student), SEEK_SET); fread(&gril1, sizeof(struct Student),1, fp); printf("姓名 %s 年龄%d 成绩%.2f\n",gril1.name,gril1.age,gril1.score); } return 0; }
10.文件结束检函数feof
feof(fp)也就是找文件结束的标志。
读写出错函数 ferror (文件指针);
能检查文件在输入输出时读写是否出错 如果ferror返回的时0就表示没有出错,否则表示文件有错。
文件出错标志和文件结束标志函数
clearerr(文件指针) 用于清除错误标志和文件结束标志,使他们为0值
相关文章推荐
- API之FindWindowEx和SendMessage
- C语言中让人头痛的指针和内存
- C++ 继承与接口 知识点 小结(二)
- C++ 虚函数与纯虚函数 浅析
- C++指针
- c语言二维数组与指针
- 实用程序软件包(关于使用静态函数报错问题“Static function declared but not defined in C+++ "eh.h is only for C++!"报错问题)
- C++ 打印矩阵
- UVa247 Floyd判断可达 深搜求环
- 黑马程序员----- c语言结构体
- c语言常用代码积累
- PAT (Basic Level) Practise (中文)1040. 有几个PAT(25) C语言
- 正则表达式
- 7.25日开始整理的东西
- C++异或运算符及作用
- sizeof单目运算符求字节数
- 关于Java与c++隐藏、重写不同实现机制的探讨
- C++静态库与动态库
- C++类保护函数外部调用
- C++入门经典 笔记(第七章)使用数组和字符串存储信息