文件操作~

news2024/12/23 11:48:01

目录

1.为什么使用文件?

2.什么是文件?

2.1 程序文件

2.2 数据文件

2.3 文件名

3.⼆进制文件和文本文件?

4.文件的打开和关闭

4.1 流和标准流

4.1.1 流

4.1.2 标准流

4.2 文件指针

4.3 ⽂件的打开和关闭

5.文件的顺序读写

5.1 顺序读写函数介绍

5.1.1什么是EOF

5.1.2 fputc函数

5.1.3 fgetc函数

5.1.4 fputs函数

5.1.5 fgets

5.1.6 fprintf函数

5.1.7 fscanf函数

5.1.8 fwrite函数

5.1.9fread函数

5.2 对比⼀组函数:

6.文件的随机读写

6.1fseek

6.2ftell

6.3 rewind

7.文件读取结束的判定

7.1 被错误使用的 feof

8. ⽂件缓冲区


1.为什么使用文件?

如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。

2.什么是文件?

磁盘(硬盘)上的文件是文件。

但是在程序设计中,我们⼀般谈的⽂件有两种:程序文件、数据文件(从文件功能的角度度来分类的)。

2.1 程序文件

程序文件包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。

2.2 数据文件

文件的内容不⼀定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

本章讨论的是数据文件。

在以前各章所处理数据的输⼊输出都是以终端为对象的,即从终端的键盘输⼊数据,运行结果显示到显示器上。

其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上文件。

2.3 文件名

⼀个文件要有⼀个唯⼀的文件标识,以便用户识别和引用。

文件名包含3部分:文件路径+文件名主干+文件后缀

例如: c:\code\test.txt

为了方便起见,⽂件标识常被称为文件名。

3.⼆进制文件和文本文件?

根据数据的组织形式,数据文件被称为⼆进制文件和文本文件?

数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存的文件中,就是⼆进制文件

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

⼀个数据在文件中是怎么存储的呢?

字符⼀律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。

如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符⼀个字节),而⼆进制形式输出,则在磁盘上只占4个字节。

用二进制写入,用文本文件不能打开,只能使用二进制的形式打开

#include <stdio.h>
​
int main() {
    int a = 1000;
    FILE* pf = fdopen("test.txt", "wb");
    fwrite(&a, 4, 1, pf); //找到a的地址写入,写入四个字节,写入一次,找到关联的文件
    fclose(pf);
    pf = NULL;
    return 0;
}

4.文件的打开和关闭

4.1 流和标准流

4.1.1 流

流-->一个媒介,连接程序和外部设备

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。

C程序针对文件、画面、键盘等的数据输入输出操作都是通过流操作的。

⼀般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作,最后关闭流

4.1.2 标准流

那为什么我们从键盘输入数据(在C语言中),向屏幕上输出数据,并没有打开流呢?

那是因为C语⾔程序在启动的时候,默认打开了3个流:

  • stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。

  • stdout - 标准输出流,⼤多数的环境中输出到显示器界面,printf函数就是将信息输出到标准输出流中。

  • stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯

这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进行输入输出操作的。

stdin、stdout、stderr 三个流的类型是: FILE * ,通常称为文件指针。

C语言中,就是通过 FILE* 的文件指针来维护流的各种操作的。

4.2 文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。

每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE.

例如,VS2013 编译环境提供的 stdio.h 头文件中有以下的文件类型申明:

struct _iobuf {
 char *_ptr;
 int _cnt;
 char *_base;
 int _flag;
 int _file;
 int _charbuf;
 int _bufsiz;
 char *_tmpfname;
};
typedef struct _iobuf FILE;

每当打开⼀个文件的时候,系统会根据文件的情况自动创建⼀个FILE结构的变量,并填充其中的信息,使用者不必关心细节。⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

下⾯我们可以创建⼀个FILE*的指针变量:

FILE* pf;//⽂件指针变量

定义pf是⼀个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是⼀个结构体变量)。通过该⽂件信息区中的信息就能够访问该文件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件

4.3 ⽂件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。

在编写程序的时候,在打开文件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建立了指针和文件的关系。

ANSI C 规定使用 fopen 函数来打开文件, fclose 来关闭文件。

文件操作,文件中有路径的话 最好加上两个斜杠

  • E:\C\Code\Cproject\practice6.17\practice6.17(绝对路径)

  • 如果用相对路径, " . " 表示当前路径 ". ."表示上一级路径

    • 那我们要访问该路径的上一级路径的文件时, " .\ \ ..\ \ test.txt "

int main() {
    //1.打开文件
    //打开成功返回一个有效的指针
    //打开失败,返回NULL(判断文件指针是否为空)
    FILE* pf = fopen("test.txt", "w"); //D:\\WeGameApps\\
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.写文件操作
    //...
​
    //关闭文件
    fclose(pf);
​
}

5.文件的顺序读写

5.1 顺序读写函数介绍

文件按照顺序去读写,光标

5.1.1什么是EOF

在C语言中,EOF(End of File)是一个特殊的标记,用于表示文件的结尾。当我们读取文件或者输入数据时,EOF可以帮助我们确定何时到达了文件的末尾。本文将详细介绍EOF的意义和用法,并提供一些示例代码以帮助理解。

  1. EOF的意义 EOF在C语言中用于标识文件的结尾。当我们从文件中读取数据时,EOF可以告诉我们何时已经读取完了文件中的所有内容。这对于文件的处理非常重要,因为它允许我们在读取文件时判断何时停止读取并继续执行其他操作。

  2. EOF的用法 在C语言中,我们可以使用EOF常量来表示文件的结尾。EOF的值是一个特殊的整数常量,通常被定义为-1。当我们从文件中读取数据时,EOF常量可以与读取的字符进行比较,以确定是否已经到达了文件的结尾。

如下代码从文件中读取所有字符 等于EOF就是到了文件结尾,结束循环

while((ch = fgetc(pf)) != EOF)

5.1.2 fputc函数

写字符操作,一个个字符写入 该函数有两个参数 ---> fputc(i,pf); // i表示要写入的内容 pf 文件指针流

int main() {
    //1.打开文件
    //打开成功返回一个有效的指针
    //打开失败,返回NULL(判断文件指针是否为空)
    FILE* pf = fopen("test.txt", "w");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.写文件操作
    int i = 0;
    for (int i = 'a'; i <= 'z'; i++) {
        fputc(i,pf); // i表示要写入的内容 pf 文件指针流
    }
​
    //关闭文件
    fclose(pf);
​
}

5.1.3 fgetc函数

读字符函数, fgetc(pf), 只有一个参数(文件指针流)

int main() {
    //1.打开文件
    //打开成功返回一个有效的指针
    //打开失败,返回NULL(判断文件指针是否为空)
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.读文件操作
    int ch = fgetc(pf); //读取到一个字符赋值给ch 然后光标就往下
    printf("%c\n", ch);
    ch = fgetc(pf);    //再读取一个 赋值给ch 光标再往下
    printf("%c\n", ch);
    ch = fgetc(pf);
    printf("%c\n", ch);
​
    //关闭文件
    fclose(pf);
    pf = NULL;
}

另外一种读 操作 使用EOF

int main() {
    //1.打开文件
    //打开成功返回一个有效的指针
    //打开失败,返回NULL(判断文件指针是否为空)
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.读文件操作
    int ch = 0;
    while ((ch = fgetc(pf)) != EOF)
    {
        printf("%c", ch);
    }
​
    //关闭文件
    fclose(pf);
​
}
  • 在上面我们所提到的标准流 stdin和stdout也可以用上面的读写函数,他们适合所有的输入输出流

  • 实现在屏幕输入一个字符,在屏幕输出一个字符

int main() {
    int ch = fgetc(stdin);
    fputc(ch, stdout);
    return 0;
}

5.1.4 fputs函数

int fputs ( const char * str, FILE * stream ); 

文本输入函数, 第一个参数是输入一个字符串,第二个参数是文件指针流

int main() {
    //1.打开文件
    FILE* pf = fopen("test.txt", "w");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.操作文件
    fputs("i am a man", pf);
    //3.关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

5.1.5 fgets

char * fgets ( char * str, int num, FILE * stream );

第一个参数用一个字符数组存储读到的字符串,第二个参数,最多读到多少个字符,第三个参数文件指针流

注意:在读字符的时候,实际读到的只是(num-1)个字符因为包含了一个\0,或者遇到换行的时候也会终止读取

int main() {
    //1.打开文件
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.操作文件
    char arr[20] = { 0 };
    fgets(arr, 5, pf);
    printf("%s", arr);
    //3.关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

同样以上两个函数同样适合所有的输入输出流,以下实现在屏幕输入和输出字符串

int main() {
    char arr[20] = {0};
    fgets(arr, 10, stdin);
    fputs(arr, stdout);
}

5.1.6 fprintf函数

int fprintf ( FILE * stream, const char * format, ... )

格式化输出函数(所有类型都可以) ,适合所有输出流,该函数和printf函数多了个文件指针流,

int main() {
    char name[20] = "aaa";
    int age = 20;
    float score = 95.7f;
    //1.打开文件
    FILE* pf = fopen("test.txt", "w");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.操作文件
    fprintf(pf, "%s %d %.1f", name, age, score);
    //3.关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

我们也可以把数据放到结构体里

struct S
{
    char name[20];
    int age;
    float score;
};
​
​
int main() {
    struct  S s = { "lisi",18,96.2f };
    //1.打开文件
    FILE* pf = fopen("test.txt", "w");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.操作文件
    fprintf(pf, "%s %d %.1f", s.name, s.age, s.score);
    //3.关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

5.1.7 fscanf函数

int fscanf ( FILE * stream, const char * format, ... );

要先把数据读出放到一个结构体中,再输出到屏幕

struct S
{
    char name[20];
    int age;
    float score;
};
​
​
int main() {
    struct  S s = { 0 };
    //1.打开文件
    FILE* pf = fopen("test.txt", "r"); //读文件
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.操作文件
    //name不用加&符号,因为本来name就是数组首元素地址
    //把文件中的数据读出来后放到结构体中
    fscanf(pf, "%s %d %.1f", s.name, &(s.age), &(s.score)); 
    //再把结构体的数据读出
    printf(" %s %d %.1f", s.name, s.age, s.score);
    //3.关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

5.1.8 fwrite函数

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

第一个参数,取需要写入文件的数据的地址,第二个参数该数据的大小,第三个参数该数据的个数,

以二进制的形式输出到文件中

struct S
{
    char name[20];
    int age;
    float score;
};
int main() {
    struct  S s = { "lisi",18,96.2f };
    //1.打开文件 二进制形式写入
    FILE* pf = fopen("test.txt", "wb");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.操作文件
    fwrite(&s, sizeof(struct S), 1, pf);
    //3.关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}
​

5.1.9fread函数

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

将文件中以二进制的形式读出放到ptr指向的空间里

struct S
{
    char name[20];
    int age;
    float score;
};
int main() {
    struct  S s = { "lisi",18,96.2f };
    //1.打开文件 二进制形式写入
    FILE* pf = fopen("test.txt", "rb");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.操作文件
    fread(&s, sizeof(struct S), 1, pf);
    printf("%s %d %f", s.name, s.age, s.score);
    //3.关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}
​

5.2 对比⼀组函数:

  • scanf/fscanf/sscanf

  • printf/fprintf/sprintf

  • 这里重点介绍sscanf函数和sprintf函数

    1.sprintf函数,将其他类型的数据转化成字符串

    struct S
    {
        char name[20];
        int age;
        float score;
    };
    ​
    int main() {
        char arr[100] = {0};
        struct  S s = { "aa",17,96.2f};
        sprintf(arr, "%s %d %f", s.name, s.age, s.score);
        printf("%s\n", arr);
        return 0;
    }

    2.sscanf函数 将字符串转化成其他类型的数据

    struct S
    {
        char name[20];
        int age;
        float score;
    };
    ​
    int main() {
        char arr[100] = {0};
        struct  S s = { "aa",17,96.2f};
        //临时变量
        struct S tmp = { 0 };
    ​
        sprintf(arr, "%s %d %f", s.name, s.age, s.score);
        /*printf("%s\n", arr);*/
        sscanf(arr, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
        printf("%s %d %f", tmp.name, tmp.age, tmp.score);
        return 0;
    }

6.文件的随机读写

6.1fseek

根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)。

 int fseek ( FILE * stream, long int offset, int origin );

offsetof --- 计算结构体成员相比于起始位置的偏移量

我们看下面代码 如果想单独读字符e就会比较麻烦,我们可以用fseek函数

int main() {
    FILE* pf = fopen("test.txt", "rb");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.读文件
    int ch = fgetc(pf); //读取到一个字符赋值给ch 然后光标就往下
    printf("%c\n", ch);
    ch = fgetc(pf);    //再读取一个 赋值给ch 光标再往下
    printf("%c\n", ch);
    ch = fgetc(pf);
    printf("%c\n", ch);
​
    fclose(pf);
    pf = NULL;
    return 0;
}

fseek函数,第三个参数可以有三种选项

SEEK_SET文件开头位置
SEEK_CUR文件指针指向的当前位置
SEEK_END文件末尾
int main() {
    FILE* pf = fopen("test.txt", "rb");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.读文件
    int ch = fgetc(pf); //读取到一个字符赋值给ch 然后光标就往下
    printf("%c\n", ch);
    ch = fgetc(pf);    //再读取一个 赋值给ch 光标再往下
    printf("%c\n", ch);
    fseek(pf, 2, SEEK_CUR);//在当前位置偏移两个位置找到e
    ch = fgetc(pf);    
    printf("%c\n", ch);
    fclose(pf);
    pf = NULL;
    return 0;
}

6.2ftell

返回文件指针相对于起始位置的偏移量

我们看下面代码,读完e之后往下一光标,输出偏移量为5

int main() {
    FILE* pf = fopen("test.txt", "rb");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    //2.读文件
    int ch = fgetc(pf); //读取到一个字符赋值给ch 然后光标就往下
    printf("%c\n", ch);
    ch = fgetc(pf);    //再读取一个 赋值给ch 光标再往下
    printf("%c\n", ch);
    fseek(pf, 2, SEEK_CUR);
    ch = fgetc(pf);    
    printf("%c\n", ch);
    //输出文件指针相比于文件的起始位置的偏移量
    printf("%d", ftell(pf));
    fclose(pf);
    pf = NULL;
    return 0;
}

6.3 rewind

让文件指针的位置回到文件的起始

void rewind ( FILE * stream );

7.文件读取结束的判定

7.1 被错误使用的 feof

牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。

因为文件结束有两种,1.遇到文件结尾,2.遇到错误

feof 的作用是:当文件读取结束的时候,再判断是读取结束的原因是否是:遇到文件尾结束。

feof的返回值,如果没有设置就默认返回0(还没到文件末尾),返回1的话代表已经到达文件末尾

1.文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )

例如:

  • fgetc 判断是否为 EOF .

  • fgets 判断返回值是否为 NULL .

2.二进制文件的读取结束判断,判断返回值是否小于实际要读的个数

例如:fread判断返回值是否小于实际要读的个数。

文本文件例子:

include <stdio.h>
#include <stdlib.h>
int main(void)
{
 int c; // 注意:int,⾮char,要求处理EOF
 FILE* fp = fopen("test.txt", "r");
 if(!fp) {
 perror("File opening failed");
 return EXIT_FAILURE;
 }
 //fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOF
 while ((c = fgetc(fp)) != EOF) // 标准C I/O读取⽂件循环
 { 
 putchar(c);
 }
 //判断是什么原因结束的
 if (ferror(fp))
 puts("I/O error when reading");
 else if (feof(fp))
 puts("End of file reached successfully");
 fclose(fp);
}

二进制的例子

#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{
    double a[SIZE] = { 1.,2.,3.,4.,5. };
    FILE* fp = fopen("test.bin", "wb"); // 必须⽤⼆进制模式
    fwrite(a, sizeof * a, SIZE, fp); // 写 double 的数组
    fclose(fp);
    double b[SIZE];
    fp = fopen("test.bin", "rb");
    size_t ret_code = fread(b, sizeof * b, SIZE, fp); // 读 double 的数组
    if (ret_code == SIZE) {
        puts("Array read successfully, contents: ");
        for (int n = 0; n < SIZE; ++n)
            printf("%f ", b[n]);
        putchar('\n');
    }
    else { // error handling
        if (feof(fp))
            printf("Error reading test.bin: unexpected end of file\n");
        else if (ferror(fp)) {
            perror("Error reading test.bin");
        }
    }
    fclose(fp);
}
  • ferro函数,如果返回一个非零的整数值,说明读取出问题;返回一个0则表示没有问题

小练习:写一个程序将一个txt文件的内容复制到另外一个txt文件

int main() {
    //打开文件
    FILE* pfread = fopen("test.txt", "r");
    if (pfread == NULL) {
        perror("fopen\n");
        return 1;
    }
    FILE* pfwrite = fopen("test2.txt","w");
    if (pfwrite == NULL) {
        perror("fopen\n");
        fclose(pfread); //如果打开文件操作出错,则关闭pfread流
        return 1;
    }
    //读或写文件
    int ch = 0; //返回值要为int类型
    while ((ch = fgetc(pfread)) != EOF) {
        fputc(ch, pfwrite); //ch表示要写入的字符
    }
    //关闭文件
    fclose(pfread);
    pfread = NULL;
    fclose(pfwrite);
    pfwrite = NULL;
}

8. ⽂件缓冲区

ANSIC 标准采用“缓冲文件系统” 处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘文件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

简单来说,就是不能一直让操作系统处理数据,先把数据存起来,再一次过处理,而不是每发一次就处理一次

#include <stdio.h>
#include <windows.h>
//VS2022 WIN11环境测试
int main()
{
 FILE*pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//先将代码放在输出缓冲区
 printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");
 Sleep(10000);
 printf("刷新缓冲区\n");
 fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)
 //注:fflush 在⾼版本的VS上不能使⽤了
 printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");
 Sleep(10000);
 fclose(pf);
 //注:fclose在关闭⽂件的时候,也会刷新缓冲区
 pf = NULL;
 return 0;
}

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题,防止信息丢失

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1883697.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

志愿者管理系统带讲解,保运行

技术栈 后端: SpringBoot Mysql MybatisPlus 前端: Vue Element 分为 管理员端 用户端 功能描述 用户端 管理员端 观看地址&#xff1a; B站 &#xff1a; 【毕设者】志愿者管理系统(安装讲解源码)

C++算法学习心得八.动态规划算法(6)

1.最长递增子序列&#xff08;300题&#xff09; 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&…

超详细的 C++中的封装继承和多态的知识总结<2.多态>

引言 小伙伴们我们都知道了&#xff0c;什么是封装和继承&#xff0c;在有了这个的基础上我们接着来看什么是多态。多态从字面上意思我们就可以知道&#xff0c;大概就是一个函数的不同形态&#xff0c;而且&#xff0c;前边我们在学习函数重载的时候我们已经简单的了解了如何用…

如何优化前端性能:提高网页加载速度的实用技巧

我们在前端开发中&#xff0c;性能优化是提高用户体验的关键因素。网页加载速度直接影响用户的满意度和留存率。本文将介绍几种优化前端性能的实用方法&#xff0c;帮助你提高网页加载速度。 问题描述 &#xff1a; 首先前端性能优化涉及多个方面&#xff0c;包括减少HTTP请…

【单片机与嵌入式】stm32串口通信入门

一、串口通信/协议 &#xff08;一&#xff09;串口通信简介 串口通信是一种通过串行传输方式在电子设备之间进行数据交换的通信方式。它通常涉及两条线&#xff08;一条用于发送数据&#xff0c;一条用于接收数据&#xff09;&#xff0c;适用于各种设备&#xff0c;从微控制…

万字长文|下一代系统内存数据加速接口SDXI解读

本文内容分为5章节&#xff0c;总计10535字&#xff0c;内容较多&#xff0c;建议先收藏&#xff01; 1.SDXI技术产生的背景 2.SDXI相比DMA的优势 3.SDXI实现原理与架构 3.1 描述符环原理解读 3.2 上下文管理介绍 3.3 AKey与RKey解读 3.4 错误日志和状态管理 3.5 跨Function访…

javascript 常见设计模式

什么是设计模式? 在软件开发中&#xff0c;设计模式是解决特定问题的经验总结和可复用的解决方案。设计模式可以提高代码的复用性、可维护性和可读性&#xff0c;是提高开发效率的重要手段。 单例模式 1.概念 单例模式 &#xff08;Singleton Pattern&#xff09;&#xf…

c++ 智能指针实战分析

一.智能指针的设计思路 智能指针是类模板&#xff0c;再栈上创建智能指针对象。把普通指针交给智能指针对象。智能指针对象过期时&#xff0c;调用析构函数释放普通指针的内存。 智能指针的类型 auto_ptr是C98的标准&#xff0c;c17已经弃用。unique_ptr、shared_ptr和weak_…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-41目标检测数据集

41目标检测数据集 import os import pandas as pd import torch import torchvision import matplotlib.pylab as plt from d2l import torch as d2l# 数据集下载链接 # http://d2l-data.s3-accelerate.amazonaws.com/banana-detection.zip# 读取数据集 #save def read_data_b…

Mustango——音乐领域知识生成模型探索

Mustango&#xff1a;利用领域知识的音乐生成模型 论文地址&#xff1a;https://arxiv.org/pdf/2311.08355.pdf 源码地址&#xff1a;https://github.com/amaai-lab/mustango 论文题为**“**利用音乐领域知识开发文本到音乐模型’Mustango’”。它利用音乐领域的知识从文本指…

计算机毕业设计Python深度学习美食推荐系统 美食可视化 美食数据分析大屏 美食爬虫 美团爬虫 机器学习 大数据毕业设计 Django Vue.js

Python美食推荐系统开题报告 一、项目背景与意义 随着互联网和移动技术的飞速发展&#xff0c;人们的生活方式发生了巨大变化&#xff0c;尤其是餐饮行业。在线美食平台如雨后春笋般涌现&#xff0c;为用户提供了丰富的美食选择。然而&#xff0c;如何在海量的餐饮信息中快速…

python 笔试面试八股(自用版~)

1 解释型和编译型语言的区别 解释是翻译一句执行一句&#xff0c;更灵活&#xff0c;eg&#xff1a;python; 解释成机器能理解的指令&#xff0c;而不是二进制码 编译是整个源程序编译成机器可以直接执行的二进制可运行的程序&#xff0c;再运行这个程序 比如c 2 简述下 Pyth…

2.2章节python的变量和常量

在Python中&#xff0c;变量和常量有一些基本的概念和用法&#xff0c;但需要注意的是&#xff0c;Python本身并没有内置的“常量”类型。然而&#xff0c;程序员通常会遵循一种约定&#xff0c;即使用全部大写的变量名来表示常量。 一、变量 在Python中&#xff0c;变量是一…

对不起,AI大模型不是风口

“我们正处在全新起点&#xff0c;这是一个以大模型为核心的人工智能新时代&#xff0c;大模型改变了人工智能&#xff0c;大模型即将改变世界。”——5月26日&#xff0c;百度创始人、董事长兼CEO李彦宏先生在2023中关村论坛发表了《大模型改变世界》演讲。 李彦宏指出&#…

4PCS点云配准算法实现

4PCS点云配准算法的C实现如下&#xff1a; #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/common/common.h> #include <pcl/common/distances.h> #include <pcl/common/transforms.h> #in…

PostgreSQL介绍与安装

一、PostgreSQL数据库介绍 1、什么是数据库&#xff1f; 数据库&#xff08;Database&#xff09;是按照数据结构来组织、存储和管理数据的仓库。每个数据库都有一个或多个不同的 API 用于创建&#xff0c;访问&#xff0c;管理&#xff0c;搜索和复制所保存的数据。 我们也…

JAVA医院绩效考核管理系统源码:系统优势、系统目的、系统原则 (自主研发 功能完善 可直接上项目)

JAVA医院绩效考核管理系统源码&#xff1a;系统优势、系统目的、系统原则 &#xff08;自主研发 功能完善 可直接上项目&#xff09; 医院绩效考核系统优势 1.实现科室负责人单独考核 对科室负责人可以进行单独考核、奖金发放。 2. 科室奖金支持发放到个人 支持奖金二次分配&…

同一个excel表格,为什么在有的电脑上会显示#NAME?

一、哪些情况会产生#NAME?的报错 1.公式名称拼写错误 比如求和函数SUM&#xff0c;如果写成SUN就会提示#NAME&#xff1f;报错。 2.公式中的文本值未添加双引号 如下图&#xff1a; VLOOKUP(丙,A:B,2,0) 公式的计算结果会返回错误值#NAME?&#xff0c;这是因为公式中文本…

GraphPad Prism生物医学数据分析软件下载安装 GraphPad Prism轻松绘制各种图表

Prism软件作为一款功能强大的生物医学数据分析与可视化工具&#xff0c;其绘图功能尤为突出。该软件不仅支持绘制基础的图表类型&#xff0c;如直观明了的柱状图、展示数据分布的散点图&#xff0c;以及描绘变化趋势的曲线图&#xff0c;更能应对复杂的数据呈现需求&#xff0c…

7-1作业

1.实验目的&#xff1a;完成字符收发 led.h #ifndef __GPIO_H__ #define __GPIO_H__#include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_uart.h"//RCC,GPIO,UART初始化 void init();//字符数据发送 void set_tt…