黑马程序员——ios开发基础之C语言预处理命令与文件操作
来源:互联网 发布:python哪些教程比较好 编辑:程序博客网 时间:2024/06/05 14:52
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
第一讲 预处理命令
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
宏替换,在编译之前,在源文件中,所有出现宏名的地方都用 宏代表的字符串去替换
注意:当宏出现在字符串中的时候,宏不会进行替换
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是在编译时 处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。
注意用宏定义表示数据类型和用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进行编译。因此可以使程序在不同条件下,完成不同的功能。
第一种形式的格式为:
#if 常量表达式
程序段1
#else
程序段2
#endif
它的功能是,如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。
2)#ifdef 条件编译指令
第二种形式的格式为:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的功能是,如果标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的 #else可以没有,即可以写为:
#ifdef 标识符
程序段
#endif
第二种形式的格式为:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的功能是,如果标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的 #else可以没有,即可以写为:
#ifdef 标识符
程序段
#endif
3)#ifndef 条件编译指令
第三种形式的格式为:
#ifndef 标识符
程序段1
#else
程序段2
#endif
它的功能与第二种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2 进行编译。这与第二种形式的功能正相反。
#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表示文件末尾,其值为 -1while (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;}
0 0
- 黑马程序员——ios开发基础之C语言预处理命令与文件操作
- 黑马程序员_iOS开发C语言基础之预处理命令
- 黑马程序员---iOS基础---C语言中的预处理命令
- 黑马程序员——C语言之预处理命令
- 黑马程序员——ios开发基础之C语言数据类型、运算符与输入输出
- 黑马程序员——ios开发基础之C语言程序结构分类与函数
- 黑马程序员——ios开发基础之C语言数组、指针与结构体
- 黑马程序员——ios开发基础之C语言之进制转换、位运算与内存管理
- 黑马程序员——ios基础---C语言:结构体、条件编译、文件操作
- 黑马程序员--C语言——预处理命令
- 黑马程序员——C语言基础---预处理指令
- 黑马程序员—(iOS开发)C语言字符串及预处理---(六)
- 黑马程序员——————c语言之预处理命令
- 黑马程序员------C语言基础 预处理指令、文件操作及其他
- 黑马程序员——c语言基础之文件的概念及操作
- 黑马程序员之ios学习总结——07 C语言的枚举、预处理指令
- 黑马程序员——ios开发基础之C语言概述
- 黑马程序员——12-C语言之预处理指令
- 黑马程序员——ios基础---练习:1
- "catalog" 与 "category" 的区别
- redis常用命令、常见错误、配置技巧
- 黑马程序员——TCP协议传输(下)
- SOA工程部署时报错:MDS-00054 (composite.xml does not exist)
- 黑马程序员——ios开发基础之C语言预处理命令与文件操作
- ‘tools.jar’ seems to be not in Android Studio classpath解决方法
- 《剑指offer》连续子数组的最大和
- 黑马程序员——ios基础---练习:2
- 集合对象中是线程安全
- adapter刷新
- iOS lipo 判断静态库是否支持64位
- 常用类的练习
- 黑马程序员——ios基础---练习:3