黑马程序员------C语言基础 预处理指令、文件操作及其他

来源:互联网 发布:易道打车软件 编辑:程序博客网 时间:2024/06/05 17:05

 ------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) aa

        有参数宏的使用注意事项:

       宏的形参之间可以出现空格 ,但是宏名和形参之间不能空格

        有参数宏 宏的参数最好用括号括起来

 应用使用有参宏求最大值

 #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      ab都是定义的整型变量

        INT2 a,b     也一样是整型变量

  定义指针时

    #include INT3 int*

     typedef int*  INT4 ;

     INT1 f1,f2 =NULL;  这里f1 zhiz  f2只是个整型变量 说明宏的定义知识单纯的文本复制的替换

     INT4 f1,f2 = NULL; 这里 f1f2 都是指针。

2.条件编译指令

   1. if -#elseif

   条件编译 :

   发生在预处理阶段 ,在编译之前做的事情

 核心:根据条件编译指定的代码

  条件不同,编译的部分也不同,生成的目标文件(.o)大小也不一样

   传统方式 

   int score =76;

  判断成句属于哪个成绩

    ifscore<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    DEBUG11是执行 a10 

        a=10;         否则执行 a100

 #else

        a=100;

 #endif

 3.使用条件编译指令调试bug

    #if DEBUG1 ==1   10 1显示调试信息  0不显示调试信息

  //显示调试信息

  #define Log(format,....)printf(format,##__VA_ARGS__);

 #else 

   #define Log(format,.......)

 //不显示调试信息

 #endif

二、文件操作

1。文件概念

 文件; 指存储在外部介质上数据的集合,这个数据有一个名称,叫做文件名

文件的分类 从用户角度 文件分为普通文件和设备文件

            从文件编码 文件分ascii码文件和二进制文件

 文件操作的步骤

   1)引入头文件<stdio.h>

   2)定义文件指针

   3)打开文件

   4)文件读写

   5)关闭文件

 对文件读和写是最常用的文件操作,在c语言中提供了多种文件读写的函数

    字符读写函数 fgetcfputc

    读写字符串函数 fgetsfputs

    数据快读写函数 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字符读写函数 fgetcputc

     字符读写函数是以字符(字节)为单位的读写函数。每次可以从文件读出或向文件写入一个字符

     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

     feoffp)也就是找文件结束的标志。

    读写出错函数 ferror (文件指针);

    能检查文件在输入输出时读写是否出错 如果ferror返回的时0就表示没有出错,否则表示文件有错。

    文件出错标志和文件结束标志函数

    clearerr(文件指针) 用于清除错误标志和文件结束标志,使他们为0




 

0 0
原创粉丝点击