首页 > 其他分享 >一文搞定C语言文件常规I/O操作

一文搞定C语言文件常规I/O操作

时间:2024-08-17 13:52:32浏览次数:13  
标签:fp 文件 搞定 一文 字符 写入 C语言 ptr 读取

普通文件(Ordinary Files)

普通文件,代指储存在硬盘中或外部媒体文件中的有序数据集。源文件(source file),工程文件(object file),可执行文件(executable file),乃至一组被处理的原始输入数据和输出结果均为普通文件。其中,源文件,工程文件等称之为程序文件,而对于输入输出的数据,则被称之为数据文件。

设备文件(Device Files)

顾名思义,设备文件是指与计算机主机相关联的各种外部设备。例如显示器,键盘等等。在操作系统中,其外部设备通常也会被认为是一个文件,而这些外部设备的输入输出也等同于对硬盘文件操作的读和写。

通常我们将显示器定义为标准输出文件,在显示屏上显示的信息便是标准输出文件的输出结果。

键盘的输入则是标准输入文件,从键盘输入数据等同于标准输入文件的输入。

对于标准输入输出文件,是由系统打开的,用户可直接进行使用。

C语言文件存储格式

C语言中,最主要的文件存储格式有两种:文本文件(text file)与二进制文件(binary file)。

文本文件同时也是ASCII文件,当该文件在磁盘中存放时,每一个字符都对应一个字节,用于存放其对应的ASCII码值。ASCII文件能够在屏幕上以字符样式显示。由于其内容可通过字符形式呈现,因此ASCII文件是能够进行阅读的。

二进制文件是按二进制的编码方式来存放文件的。二进制文件也能够通过屏幕进行显示,但由于是按机器码方式进行呈现,因此也是不可阅读的。

在处理这些文件时,C系统并不区分其类型,而是将其看成字符流,按字节进行处理。输入输出的字符流控制并不由物理符号控制(例如换行符等),而是由其程序进行控制。因此,这种类型的文件也称之为“流式文件”。


文件指针与文件打开关闭

FILE指针

        C语言中,无法直接对文件进行操作,其各种修改操作必须借由其指针进行。

//定义一个文件指针
FILE* your_pointer_name;
//例如
FILE* fp;	

以上语句定义了一个指向文件的指针变量。

        文件指针可对其指向的文件进行文件操作。FILE是一个结构体类型,因此其定义的指针也是指向结构体的,其中包含了文件名,文件状态,当前方位指针等等数据。

只要用户不重新分配,文件指针的值是不会改变的,一直指向该文件。

这里不去深究其中的细节,只需要了解FILE是一个结构体类型,以及如何定义一个指向文件的指针既可。


fopen()打开文件

        fopen函数包含于stdio.h文件中,用于打开文件,以及选择用户想要的操作方式,为接下来一系列的文件操作打下基础。其函数原型如下:

fopen(const char* file_name,const char* open_mode)
const char* file_name :指向一个常量字符串,即要打开文件的名称(可包含路径)。
const char* open_mode:指向一个常量字符串,既要通过什么方式打开文件(只读/只写等)。

关于返回值:

        fopen返回一个指向FILE结构体的指针,该指针用于后续的文件操作。若打开失败,则会返回NULL。因此在打开文件同时应当对其返回值进行检测,以确保文件被正确打开,避免后续操作中出现错误。

//fopen()用于打开文件. fopen命令格式
fp = fopen("file_name","open_mode");
//例如:以只写方式打开当前目录下名为DataBase.txt的文件
fp = fopen("DataBase.txt", "wt");

通过路径打开文件:

//也有如下格式。以二进制文件只写方式打开D盘下的test文件
FILE* fphzk;
//fphzk = fopen("Your_File_Path","mode");
fphzk = fopen("D:\\test", "wb");

以下为打开文件的完整步骤:

FILE* fp = fopen("Database.bin", "wb"); //以二进制只写方式打开该目录下Database.bin文件
if (fp == NULL) {		//检测返回值
	perror("Oops!Something wrong happened");
	return -1;
}

文件打开模式

文件的打开模式有如下12种方式:

1.rt        2.wt        3.at        4.rb        5.wb        6.ab        7.rt+        8.wt+        9.at+

10.rb+        11.wb+        12.ab+

其中:

r : read 可读       

w : write 可写       

a : append  追加       

text : (ASCII文本文件)       

b : binary(二进制)        

+ : read and write 可读可写

接下来以二进制文件(文本文件同理)为例来解释一下各个模式:

rb (read binary) : 以只读的方式打开一个二进制文件,该文件必须存在!用户可以读取该文件中的数据,但是不能向其中写入数据。

wb (write binary) : 以只写的方式打开一个二进制文件,若该文件不存在,则在指定目录新建一个同名文件。若该文件存在,则格式化原文件。用户不能从其中读取出数据,但是可以向其中写入。

ab (append binary) : 以追加的方式打开一个二进制文件,若该文件不存在则被创建。新写入的数据会被追加在文件末尾。(注意:追加方式文件可以从头读取文件,但是只能在文件尾端写入数据,而不能在除尾端之外的任何地方覆盖原文件数据或写入数据)

rb+(read and write binary) :以读写方式打开二进制文件,文件必须存在。

wb+(write and read binary) : 以读写方式打开二进制文件,若文件不存在则被创建,若文件存在则格式化原文件。

ab+(append and read binary) : 以读和追加的方式打开二进制文件,若文件不存在则被创建,该文件将会从头被读取,但是写入文件只能在文件末尾。

ASCII文件的打开模式与上相同。

fclose()关闭文件

当文件操作结束之后,可以用fclose()函数关闭文件,防止出现数据丢失等错误情况。

    //函数原型
    fclose(file_pointer);
    //关闭fp指向的文件
    fclose(fp);

关于返回值:

当文件正确被关闭时,将会返回0值。如果函数返回了一个非0值,则代表关闭出现了错误,文件未正常关闭。

if(fclose(fp) != 0){
        perror("Error closing the file");
        return;
    }

文件的读与写

字符的读与写

        C语言文件操作中可以对单个字符进行读写操作。单字符的读写操作基于一个字节进行读取,其中fgetc()函数用于从文件中获取一个字符,fputc()用于向文件中写入一个字符。

上述函数的每一次调用都将读取或写入一个字符到文件。

fgetc()读取字符

fgetc函数用于从文件中读取一个字符,其函数原型如下:

character variable = fgetc(file_pointer);
word.txt
adcdefg

--------------------------------------------
//打开文件word.txt,读取一个字符并打印输出
    FILE *fp = fopen("word.txt","rt");
    char ch = fgetc(fp);
    printf("%c",ch);

--------------------------------------------
输出结果: a
            

可以利用循环,从文件中读取多个字符。

word.txt
adcdefg

--------------------------------------------
FILE *fp = fopen("word.txt","rt");
    char ch;
    while((ch = fgetc(fp)) != EOF)
    {
        printf("%c",ch);
    }
--------------------------------------------
输出结果: adcdefg

        每个文件都有一个文件末尾标志符(EOF),当使用fgetc进行读取时,每读取一个字符,文件的内部指针都会向前移动一个字符,当读取到达文件末尾时,指针便指向EOF。

由于是读取字符,所以使用该函数时打开的文件应包含读取权限。

该函数可以在不给读取的数值分配字符变量时使用。


fputc()写入字符

        与fgetc()相反,fputc()函数用于向文件中写入单个字符,其函数原型如下:

 fputc(character,file_pointer);
character :传入要写入的字符,可以是字符常量,也可以是变量。
file_pointer :指向要写入文件的文件指针。
word.txt
adcdefg
-------------------------------------------- 
//将大写E写入word.txt文件
    FILE *fp = fopen("word.txt","wt");//注意此处使用的是write模式,并非append模式
    fputc('E',fp);
    fclose(fp);
-------------------------------------------- 
执行命令后的word.txt
E

由于是写入操作,所以打开的文件应当包含对应的写入权限。

每一次的字符写入,内部指针都会自行移动一个字符的位置,指向下一个即将写入的位置。

关于返回值:

        若字符被正确写入,则返回被写入的字符,若未被正确写入,则返回EOF。可以用来检查数据是否被正确写入。

 FILE *fp = fopen("word.txt","wt");
    char ch;
    if((ch=fputc('E',fp)) != EOF)   
    {
        printf("%c",ch);    //若正确写入,则输出其返回值
    }
    fclose(fp);
------------------------------------------------
运行结果:
E

可用循环配合字符数组一次性向文件中写入多个字符。

word.txt:
E

---------------------------------------------------------------
//用循环配合字符数组来向文件中写入多个字符
    FILE *fp = fopen("word.txt","at");
    char ch[5] = {'a','b','c','d'};
    int i;
    for(i=0;i<4;i++)
    {
        if(fputc(ch[i],fp) == EOF)
        {
            printf("Oops!Something wrong happened\n");
            continue;
        }
    }
    printf("Successfully writing\n");
    fclose(fp);
---------------------------------------------------------------
输出结果:
Successfully writing

---------------------------------------------------------------
word.txt:
Eabcd

getchar()读取字符

        getchar()函数也用于从文件中读取一个字符,但与fgetc()不同,该函数是从标准输入文件(通常是键盘)读取一个字符。当输入的字符被成功读取时,getchar将返回输入的字符,若遇到错误则返回EOF。

通常该函数可用于清空输入缓冲区和从键盘读入字符数据。

该函数通常是一个宏定义,等价于fgetc(stdin);

printf("Please enter a char\n");
    char ch = getchar();
    if(ch != EOF)
    {
        printf("Character from standard input:%c\n",ch);
    }
------------------------------------------------------------
输出结果:
    Please enter a char
    A
    Character from standard input:A

putchar()写入字符

        同getchar,putchar用于直接向标准输出文件(通常为显示屏)写入数据。需要一个字符常量或变量作为参数。与fputc一样,当写入成功时返回写入的字符,若发生错误则返回EOF。

通常也是一个宏定义,等价于:

fputc(character,stdout);

int result = putchar('B');
    if(result != EOF)
    {
        printf("\nThe Character B has been written to standard output\n");
    }
    else
    {
        perror("Oops!Failed to write to standard output\n");
    }
-----------------------------------------------------------------------
输出结果:
B
The Character B has been written to standard output

字符串的读与写

fgets()读取字符串

fgets用于从文件中读取字符串并存储到一个字符数组中。其函数原型如下:

 char *fgets(char* str,int num,FILE *stream);
 str : 指向用于存储读取字符串的缓冲区指针。
num : 要读取的最大字符数(包含空字符与换行符)。注意,是从文件中读取num-1个字符,最后一位将会自动补上'\0'。
stream : 指向FILE结构体的指针,表示要读取的文件。
word.txt
Eabcde
ABCD

------------------------------------------
    FILE *fp = fopen("word.txt","rt");
    char str[6];
    fgets(str,sizeof(str),fp);
    printf("%s\n",str);
    fclose(fp);
-------------------------------------------
输出结果:
Eabcd

如上述代码所示,以只读方式打开了文件word.txt,定义了一个6字节大小的字符数组str,并从文件word.txt中读取该字符数组大小的字符。而这会将第一行Eabcd五个字符读取,并在最后留空的一位补上'\0',因此屏幕上会打印Eabcd而并没有e。

现在我们将str数组大小改为11,并重新执行上述代码。

char str[11];

得到如下结果:

并未如我们预期一样恰好读取完word.txt中所有内容。

原因是fgets函数在读取时并不会关注格式,而会在读取到换行符或达到指定的最大字符数时停止读取。(注:换行符也会被包含在读取的字符串中)

关于返回值:

fgets函数也具有返回值,其返回的是字符数组的首地址。

    FILE *fp = fopen("word.txt","rt");
    char str[5];
    printf("%p\n",str);//打印str地址

    char *ptr;
    ptr = fgets(str,sizeof(str),fp);
    printf("%p\n",ptr); //打印返回值ptr指向的地址
    fclose(fp);
----------------------------------------------------
输出结果:
000000000061FDDB
000000000061FDDB

fputs()写入字符串

        fputs()函数用于将一个字符串写入到指定文件中,该函数不会自动添加换行符,因此若需换行的话需在字符串中显式包含换行符。函数原型如下:

int fputs(const char* str,FILE* stream);
str:指向要写入字符串的指针。
stream:FILE的结构体指针,指向要写入的文件。

关于返回值:

当写入成功时,将返回一个非负值,若写入失败,则返回EOF。

word.txt
Eabcde
ABCD
-------------------------------------------------------------------   

    FILE* fp;
    if((fp=fopen("word.txt","at")) == NULL) //判断是否正确打开文件
    {
        perror("Error opening the file");
        exit(EXIT_FAILURE);
    }
    if(fputs("Hello",fp) != EOF)    //写入文件并判断是否写入成功
    {
        printf("Successful writing\n");
    }
    else
    {
        perror("Failed write to the file");
        exit(EXIT_FAILURE);
    }
    fclose(fp);

-------------------------------------------------------------------  
运行结果:
Successful writing
-------------------------------------------------------------------  
word.txt
Eabcde
ABCDHello

        上述示例代码运用fputs()函数,向word.txt文件中追加了字符串常量"Hello"。现在,我们对将上述代码进行修改如下:

    FILE* fp;
    char str[20] = "This si C\n Word"; //定义一个大小为20的字符数组,并在其中显式包含换行
    if((fp=fopen("word.txt","at")) == NULL) 
    {
        perror("Error opening the file");
        exit(EXIT_FAILURE);
    }
    if(fputs(str,fp) != EOF)  //将定义的字符数组名作为参数传入 
    {
        printf("Successful writing\n");
    }
    else
    {
        perror("Failed write to the file");
        exit(EXIT_FAILURE);
    }
    fclose(fp);

-------------------------------------------------------------------  
运行结果:
Successful writing
-------------------------------------------------------------------  
word.txt
Eabcde
ABCDHelloThis si C
 Word

修改后的代码定义了一个字符数组,并在其中做了格式调整后将数组名(数组首元素地址)传入fputs进行写操作。

fputs()函数的第一个参数,既可以是字符常量,也可以是字符数组的名称,亦或是一个指针变量。


区块数据的读与写

fread()块数据的读取

        在前面,我们了解了fgetc可以从文件中读取单字符,而fgets可以从文件中读取字符串。但有时,对于一些特殊的数据类型(例如结构体)的处理,往往需要对一块数据整体进行读写处理,这就需要用到fread与fwrite功能函数了。

fread()函数原型如下:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr:也可叫做buffer,是一个指向一块内存的指针。该内存用作缓冲区来暂存从文件中读取过来的一块数据,或要写入文件的一块数据。
size:每块数据项的大小(单位为字节)。
nmemb:要读取数据块的数量。
stream:FILE结构体指针,指向要操作的文件。

换句话说,fread即从用户指定的文件流中,读取nmemb块数据文件,每块数据的大小均为size个字节,并将这些读取到的文件存储在ptr指向的内存块中,并返回成功读取的数据项数量(即如果全部成功读取将返回nmemb)。

若返回值小于nmemb,则表示出现了读取错误或达到了文件结尾。

示例代码如下:

word.txt
ABCDHelloThis si C
------------------------------------------------------  

    FILE * fp = fopen("word.txt","rt");
    int i;
    char arr[2][3]; //定义二维数组,将读取的数据分为两块,每块3字节
    //进行两次循环,每次向一个块中从文件读取3个字符
    for(i=0;i<2;i++)
    {
        size_t BytesRead = fread(arr[i],3,1,fp); 
        if(BytesRead != 1)  //对返回值进行检查
        {
            if(feof(fp))
            {
                printf("Reach the end of file\n");
            }
            else
            {
                perror("Error reading file");
                fclose(fp);
                return; //结束
            }
        } 
    }
    //打印输出两块数据
    for(i=0;i<2;i++)
    {
        for(int k=0;k<3;k++)
        {
            printf("%c",arr[i][k]);
        }
        printf("\t");
    }
    fclose(fp); //记得关闭文件

------------------------------------------------------
输出结果:
ABC    DHe

fwrite()块数据的写入

        同fread,fwrite用于对整块数据进行写入。其函数原型如下:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr:也可叫做buffer,是一个指向一块内存的指针。该内存用作缓冲区来暂存从文件中读取过来的一块数据,或要写入文件的一块数据。
size:每块数据项的大小(单位为字节)。
nmemb:要读取数据块的数量。
stream:FILE结构体指针,指向要操作的文件。

fwrite函数从ptr所指向的内存块中,读取nmemb块数据,每块数据大小为size个字节。写入成功后返回成功写入的数据(若全部写入成功将返回nmemb)。如果返回值小于nmemb,则说明写入出错。

    int i;
    int arr[5] = {1, 2, 3, 4, 5};
    FILE *fp = fopen("data.bin", "wb"); //二进制方式创建一个文件并打开
    if (fp == NULL)
    {
        perror("Error opening the file");
        return;
    }
    size_t BytesWrite = fwrite(arr,sizeof(int),5,fp);   //写入数组arr中的数据,并记录返回值
    if(BytesWrite != 5) //通过返回值检查是否写入成功
    {
        perror("Error write to the file");
    }
    else
    {
        printf("Successful write\n");
    }
    fclose(fp); //关闭文件
------------------------------------------------------
输出结果:
Successful write

执行上述代码,用十六进制打开创建的data文件,可以看到

说明已经写入成功。

区块数据读写操作示例代码

/*自定义一个学生类,由用于输入学生数据后,将数据写入到文件保存并且读取出来打印到
显示器上*/

#include <stdio.h>
#include <process.h>
#include <windows.h>
#include <string.h>
#define ARR_RANGE 3 //宏定义,学生类型数组大小

//定义一个学生类型结构体
typedef struct Student
{
    char Name[20];
    int Age;
    int ID;
}student;

//函数声明
void studentInput(struct Student* ptr); 
void studentRead(struct Student* ptr);
void studentWrite(struct Student* ptr);
void studentDisplay(struct Student* ptr);
void clearInputBuff();

int main(int argc,const char* argv[])
{
    SetConsoleOutputCP(CP_UTF8);

    student stu[ARR_RANGE]; //学生类型结构体数组
    studentInput(stu);  //输入学生数据
    studentWrite(stu);  //写入学生数据
    studentRead(stu);   //读取学生数据
    studentDisplay(stu);    //显示学生数据
    system("pause");
    system("cls");
    return 0;

}

void studentInput(struct Student* ptr)  //输入数据
{
    char _name[20];
    int _age;
    int _id;

    for(int i=1;i<ARR_RANGE+1;i++)
    {
        system("cls");
        printf("请输入%d号学生信息\n",i);

        printf("请输入姓名\n");
        fgets(_name,sizeof(_name),stdin);   //从键盘读取数据存入字符数组
        _name[strcspn(_name,"\n")] = '\0';  //剔除掉输入数据中的换行符

        printf("请输入年龄\n");
        scanf("%d",&_age);

        printf("请输入学号\n");
        scanf("%d",&_id);
        clearInputBuff();

        //为结构体类变量赋值
        strcpy(ptr->Name,_name);
        ptr->ID = _id;
        ptr->Age = _age;
        ptr++;
    }
    system("cls");
    printf("Successful inputing\n");
    Sleep(1000);
    ptr=NULL;
}

void studentRead(struct Student* ptr)   //读取数据
{
    system("cls");
    FILE *fp = fopen("Database.bin","rb");
    if(fp == NULL)
    {
        perror("Error opining the file");
        return;
    }
    size_t BytesRead = fread(ptr,sizeof(student),ARR_RANGE,fp);
    if(BytesRead != ARR_RANGE)  //对返回值进行检查,确保正确读取
    {
        perror("Error read the file");
        exit(1);
    }
    else
    {
        printf("Successful reading\n");
        Sleep(1000);
    }
    ptr=NULL;
    fclose(fp);
}

void studentWrite(struct Student* ptr)  //写入数据
{
    system("cls");
    FILE *fp = fopen("Database.bin","wb");  //二进制方式创建并打开文件Database.bin
    if(fp == NULL)
    {
        perror("Error opening the file");
        return;
    }
    size_t BytesWrite = 0;
    //从ptr指向的内存块中写入数据
    while(fwrite(ptr,sizeof(student),1,fp) == 1){
        BytesWrite++;
        ptr++;
        if(BytesWrite == ARR_RANGE)
        {
            break;
        }
    }
    printf("Successful Writing\n");
    Sleep(1000);    //延时1秒
    ptr=NULL;
    fclose(fp);
}

void studentDisplay(struct Student* ptr) //显示数据
{
    for(int i=0;i<ARR_RANGE;i++)
    {
        printf("Name:%s\n",ptr->Name);
        printf("Age:%d\n",ptr->Age);
        printf("Student ID:%d\n\n\n",ptr->ID);
        ptr++;
    }
    ptr=NULL;
}

void clearInputBuff()
{
    char ch;
    while(ch != EOF && (ch=getchar()) != '\n'){}
}

运行结果如下:

标签:fp,文件,搞定,一文,字符,写入,C语言,ptr,读取
From: https://blog.csdn.net/R6bandito/article/details/141187126

相关文章

  • C语言-写一个用矩形法求定积分的通用函数,分别求积分区间为[0,1]sinx,cosx,e的x方的定积
    一、题目要求:二、思路①数学方面:矩形法求定积分的公式将积分图形划分成为指定数量的矩形,求取各个矩形的面积,然后最终进行累加得到结果1.积分区间:[num1,num2]2.分割数量:count每个矩形的边长:dx=(num2-num1)/count3.被积分函数:f(x)(f-对应不同的被积分函数sin......
  • 深入探索CSS的:local-link伪类:选择指向同一文档的链接
    CSS(层叠样式表)是控制网页样式的核心语言,它允许开发者根据元素的不同状态和特性来应用样式。:local-link伪类是CSS中一个相对较少被讨论的选择器,它专门用于选择那些指向同一文档内锚点的链接。本文将详细介绍:local-link伪类的使用方式、应用场景以及如何通过它们增强网页的......
  • 如何让你的C语言程序打印的log多一点色彩?(超级实用)
    接着上一篇文章《由字节对齐引发的一场“血案“》在平常的调试中,printf字体格式与颜色都是默认一致的。如果可以根据log信息的重要程度,配以不同的颜色与格式,可以很方便的查找到要点。1、printf字体显示语法说明printf(“\033[显示方式;字体颜色;背景颜色m字符串\033[0m”)......
  • 新员工一口气写完了这些C语言例子,领导给他转正了!
    持续更新中...很多想从事嵌入式Linux开发的老铁问一口君,有没有快速提升自己编程水平的小例子?一口君根据自己多年工作经验,整理了一些基于Linux的c语言的非常实用的小例子,这些例子在嵌入式开发工作中,或多或少都会用到。看看你们会做多少?一、基础C语言1.排序算法给指定数组排......
  • Python解释器如何下载+如何安装+配置环境+踩坑 一文搞定【保姆级图文教程】
    如果你要学Python,那么第一件事情就是先去安装。因为你的电脑里面没有Python,编写好的.py文件就没有解释器可以运行,所以安装Python环境/解释器就是最重要的一件事。PS:本文仅为笔记,为个人整理而成,如有不足之处请多多指正。目录第一步:下载1.官方网站2.镜像源网站第二步......
  • 一文快速了解开源表单快速开发的多个优势
    帮助企业提升效率、降低成本、做好数据治理,是低代码技术平台的发展优势。了解低代码技术平台的客户朋友都知道,它拥有可视化操作界面、更高效、更可靠、更灵活等优势,是助力企业降本增效的助手。本文将从各个方面为大家解析什么是低代码技术平台,以及开源表单快速开发的优势特点。先......
  • 一文读懂!如何选择最适合的开源项目管理工具
    国内外主流的10款开源项目管理系统对比:PingCode、Worktile、Gitee、开源中国(OSChina)、禅道(ZenTao)、OpenProject、Redmine、Leantime、MeisterTask、Freedcamp。在选择合适的开源项目管理工具时,你是否感到困惑和不安?市场上众多的选项和技术参数可能让你不知所措,而正确的......
  • Java 开发者必备:一文解决 AES 加密中的“非法密钥大小”异常
    彻底告别java.security.InvalidKeyException,轻松应对不同JDK版本引言在Java开发过程中,我们经常会遇到各种各样的安全相关的问题。其中一个常见的问题是当使用Java的加密功能时遇到的“Illegalkeysizeordefaultparameters”错误。本文将详细介绍如何解决这一问......
  • 【漫谈C语言和嵌入式002】嵌入式中的大小端
            在计算机科学中,"端序"(Endianness)是指多字节数据类型(如整数或浮点数)在内存中的存储方式。主要分为两种:大端模式(Big-Endian)和小端模式(Little-Endian)。大端模式(Big-Endian)       在大端模式中,多字节数据类型的最高有效字节(MSB)被存储在最低的内存地址......
  • C语言学习 --- 冒泡排序与二分查找
    冒泡排序 排序        从小到大顺序排 轮数        数据个数-1 每一次比较的次数      数据个数-1-当前的轮数      每次比较开始从下标为0的地方开始比较     轮数:0~<数据个数-1次数:0~<数......