黑马程序员——ios开发基础之C语言预处理命令与文件操作

时间:2023-02-18 17:50:49
------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
     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.h
                     2) 定义文件指针
                     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;
}