暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

第七天:C语言文件和存储类别

瓶子的跋涉 2023-01-11
214

1字节(byte)= 比特8(bit)

字长:指CPU一次能够运算的数据的位数,不同计算机不同。例如64位计算机的CPU一次最多处理64位数据。

位:数据存储的最小单位,在二进制系统中,每个0或1就是一个位(bit)


存储类别

  • 自动变量 auto

  • 静态变量 atatic

  • 寄存器变量  register

  • 外部变量 extern


自动变量:通常在自定义函数内或代码段中(用“{}”)括起来,定义的变量,都是自动变量,除了加了static关键字修饰的变量,也称为 局部变量

外部变量:(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。(如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件末尾。如何在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量进行“外部变量声明”。表示该 变量是一个已经定义的外部变量。)

静态变量: 有时希望函数中的局部变量的值在函数调用结束后不消失保留原值,这就应该指定局部变量为静态局部变量,用关键字static 进行声明。

寄存器变量:为提高效率,C语言允许将局部变量的值存放在CPU的寄存器中,用关键字 register 声明,

注意:

  • 只有局部自动变量和形式参数可以作为寄存器变量

  • 一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量

  • 不能使用取地址运算符 “&” 求寄存器变量的地址


动态内存分配

  • malloc

  • calloc  :与malloc的区别:calloc会把申请的空间的每个字节初始化为全0

    void* calloc(size_t num, size_t size);
    // 为num个大小为size的元素开辟一款空间,并且把空间的每一个字节初始化为0

    realloc:可以做到对动态开辟内存大小的调整


      void* realloc(void * ptr,size_t size);
      // pst是要调整额内存地址
      // size调整之后新大小
      // 返回值为调整之后的内存起始位置
      // 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间

      realloc在调整内存空间时存在两种情况

      • 原有空间之后有足够大的空间,扩展内存就在原有内存之后直接追加空间,原有空间的数据不发生变化

      • 原有空间之后没有足够多的空间,在堆空间上另找一个适合大小的连续空间来使用。这样函数返回的是一个新的内存地址,。

        • 如果realloc申请失败返回NULL指针,老空间ptr被置空,造成内存泄露无法找到原有的内存地址。


      文件操作

      声明库:

        #include <stdio.h>

        打开文件

          FILE * fp;
          fp = fopen(char * str1,"str2");
          // str1为该文件的文件名(即路径),第二为C语言规定的模式字符串

          文件指针底层原理:每个被使用的文件,都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(文件名,文件状态,文件位置等)这些信息被保存到结构体中,系统为其声明为FILE,每当打开一个文件的时候,系统就会根据情况自动创建一个FILE结构的变量,并且FILE*指针来维护这个结构。


          在main.cpp创建文件 hello.txt ,写入些内容

            #define _CRT_SECURE_NO_WARNINGS
            #include <stdio.h>


            int main()
            {
            int ch; 用int类型的变量存储EOp
            FILE* fp = NULL;
            fp = fopen("hello.txt", "r"); 打开文件采用读的方式
            while ((ch = getc(fp)) != EOF)
            {
                putchar(ch);//输出
            }
            fclose(fp);
            }

            文件关闭

              int fclose(FILE* stream)


              文件的使用方式:

              输入内容:

                   char * strerror(int errnum)
                   // 从内存数组中搜索错误号errnum,并返回一个指向错误消息字符串的指针,
                   // strerror 生成错误字符串取决于开发平台和编译器
                   // 参数errnum 错误号,通常是errno
                  #define _CRT_SECURE_NO_WARNINGS
                  #include <stdio.h>
                  #include <string.h>
                  #include <errno.h>


                  int main()
                  {
                  int ch; 用int类型的变量存储EOp
                  FILE* fp = NULL;
                  fp = fopen("hello.txt", "w+"); 打开文件采用读的方式
                  if (fp == NULL)
                  {
                  printf("%s\n", strerror(errno));
                  return 0;
                  }
                  写入一个字符
                  fputc('a', fp);
                  fclose(fp);
                  fp = NULL;
                  return 0;
                  }


                  读取一个字符

                    int ch =fgetc(fp);
                    if(ch!=EOF) // 如果读取的
                    {
                    printf("%c",ch);
                    }


                    读取指定长度的数据

                      //定义一个数组
                      char arr[10] = {0};
                      // 在文件指针fp当中读取前五个数据,存放到arr数组当中
                      fgets(arr,5,fp);  //将所读取的数据放入arr中
                      printf("%s\n",arr)

                      将结构体信息写入文件中

                        #define _CRT_SECURE_NO_WARNINGS
                        #include <stdio.h>
                        #include <string.h>
                        #include <errno.h>
                        typedef struct S
                        {
                        char name[10];
                        int age;
                        }stu;
                        int main()
                        {
                        FILE* pf = fopen("stu.txt", "w");
                        if (pf != NULL)
                        {
                        stu s = { "小明",18 };
                            // 文件指针 文件写入格式 文件内容
                        fprintf(pf, "%s %d\n", s.name, s.age);
                        fclose(pf);
                        pf = NULL;
                        }
                        return 0;
                        }
                        /* 文件中保存.....
                        小明 18
                        */

                        读取文件到结构体中:

                          #define _CRT_SECURE_NO_WARNINGS
                          #include <stdio.h>
                          #include <string.h>
                          #include <errno.h>
                          typedef struct S
                          {
                          char name[10];
                          int age;
                          }stu;
                          int main()
                          {
                          FILE* pf = fopen("stu.txt", "r");
                          if (pf != NULL)
                          {
                          stu s;
                              //在文件指针pf中按照 字符串 整型 的格式保存到结构体指针中
                          fscanf(pf, "%s %d", s.name, &s.age);
                          printf("%s %d\n", s.name, s.age);
                              fclose(pf); //关闭pf文件指针
                              pf = NULL; //将文件还真赋值为空
                          }
                          return 0;
                          }
                          // 将stu.txt 文件的内容读取出来

                          文件的随机读写:指定我们想要读写的位置

                          fssek()函数:该函数可以从定位位置的偏移量处开始读写

                            int fseek(FILE*stream,long offset,int origin)
                            //参数分别为 文件流 偏移量,起始位置指针(固定的)
                            // 返回值
                            // 如果成功,fseek返回0,否则它返回一个非零值,在无法查找的设备行,返回值未定义

                            三种定位指针

                            名称参考位置
                            SEEK_SET
                            文件开始位置
                            SEEK_CUR
                            当前的文件指针点
                            SEEK_END
                            文件结束点

                            举例:(26英文字母的文件)

                              #define _CRT_SECURE_NO_WARNINGS
                              #include <stdio.h>
                              #include <string.h>
                              #include <errno.h>
                              int main()
                              {
                              FILE* pf = fopen("a.txt", "r");
                              if (pf == NULL)
                              {
                              printf("%s\n", strerror(errno));
                              return 0;
                              }
                              定位指针,从开头向后偏移5个单位
                              fseek(pf,5, SEEK_SET);
                              int ch = fgetc(pf);
                              printf("%c\n", ch);
                              //第二次读取,当前指针向后便宜5个单位
                              fseek(pf, 3, SEEK_CUR);
                              ch = fgetc(pf);
                              printf("%c\n", ch);
                              //第三次读取,从文件末尾向前偏移3个单元
                              fseek(pf,-8, SEEK_END);
                              ch = fgetc(pf);
                              printf("%c\n", ch);
                              //关闭文件
                              fclose(pf);
                              pf = NULL;
                              return 0;
                              }

                              注意:

                                  在每次使用完一次fssek函数后,文件指针会自动向后移动一位。

                              ftell函数:该函数可以返回文件指针相对于起始位置的偏移量

                                long int ftell(FILE*stream);

                                rewind()函数:让文件到文件初始位置

                                  void rewind(FILE* stream);
                                    #define _CRT_SECURE_NO_WARNINGS
                                    #include <stdio.h>
                                    #include <string.h>
                                    #include <errno.h>
                                    int main()
                                    {
                                    FILE* pf = fopen("a.txt", "r");
                                    if (pf == NULL)
                                    {
                                    printf("%s\n", strerror(errno));
                                    return 0;
                                    }
                                    //定位指针,从开头向后偏移5个单位
                                    fseek(pf,5, SEEK_SET);
                                    int ch = fgetc(pf);
                                    printf("%c\t", ch);
                                    //s输出相对于起始位置的偏移量
                                    printf("%d\n", ftell(pf));
                                    //第二次读取,当前指针向后偏移5个单位
                                    //让文件指针回到文件初始位置
                                    rewind(pf);
                                    fseek(pf, 3, SEEK_CUR);
                                    ch = fgetc(pf);
                                    printf("%c\t", ch);
                                    printf("%d\n", ftell(pf));
                                    //第三次读取,从文件末尾向前偏移3个单元
                                    fseek(pf,-8, SEEK_END);
                                    ch = fgetc(pf);
                                    printf("%c\t", ch);
                                    printf("%d\n", ftell(pf));
                                    //关闭文件
                                    fclose(pf);
                                    pf = NULL;
                                    return 0;
                                    }

                                    二进制写入文件

                                      size_t fwrite(const void *buffer,size_t size, size_t count, FILE*stream);

                                      例如:

                                        Peo p = { "lisi", 19 };
                                        fwrite(&p, sizeof(Peo), 2, pf);
                                        fclose(pf);
                                        pf = NULL;

                                        读取二进制文件信息

                                          size_t fread(void * buffer,size_t size,size_t count ,FILE*stream);
                                            Peo p = { 0 };


                                            fread(&p, sizeof(Peo), 1, pf);


                                            printf("%s %d\n", p.name, p.age);


                                            fclose(pf);
                                            pf = NULL;


                                            文件读取结束原因函数feof()函数

                                            文件读取结束有两种情况:

                                            • 读取过程中出现异常

                                            • 读取到文章末尾

                                            文本文件

                                            • 如果用fgetc()读取,要判断feof()的返回值是否为EOF

                                            • 如果用fgets()读取,要判断feof()的返回值是否为NULL(0);

                                            二进制文件:

                                                都是使用fread()读取,要判断其返回值与指定读取个数的大小,如果小于实际要读的个数,就说明发生读取异常,如果等于实际要读的个数,就说明是因读取成功而结束;对于读取异常的判断,我们考虑判断ferror()函数的返回值。

                                            • 若ferror()为-----异常读取而结束

                                            • 若feof()为真-------正常读取到而结束


                                            文章转载自瓶子的跋涉,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                            评论