C语言文件操作【详解】

news2025/1/13 2:49:53

在这里插入图片描述

本期介绍🍖
主要介绍:为什么使用文件,什么是文件,文件的打开和关闭的操作方法,文件的顺序读写于随机读写,文件读取结束的判定👀。


文章目录

  • 一、为什么使用文件🍖
  • 二、什么是文件🍖
    • 2.1 程序文件🍖
    • 2.2 数据文件🍖
    • 2.3 文件名🍖
  • 三、文件的打开和关闭🍖
    • 3.1 fopen函数🍖
    • 3.2 fclose函数🍖
  • 四、文件读写🍖
    • 4.1 文件的顺序读写🍖
      • 4.1.1 按字符读和写【fgetc && fputc】🍖
      • 4.1.2 按字符串读和写【fputs && fgets】🍖
      • 4.1.3 格式化的读和写【fprintf && fscanf】🍖
      • 4.1.4 以二进制的形式读和写【fwrite && fread】🍖
    • 4.2 文件的随机读写🍖
      • 4.2.1 fseek函数🍖
      • 4.2.2 ftell函数🍖
      • 4.2.3 rewind函数🍖
  • 五、文件读取结束的判定🍖


一、为什么使用文件🍖

  文件存在的意义就是为了能够让数据持久化的存在于电脑中。为什么这么说呢?你想啊,如果你在运行一个程序时没有将其数据保存下来,那么下一次再打开这个程序时,之前运行的数据必然不存在了(因为在程序运行时数据只是暂时存放于内存中,如若没有及时保存一旦程序结束,操作系统会回收这些运行时所占用的空间,故下一次运行时之前的数据自然就不存在了)。

  所以为了能够将一些数据记录下来、保存下来、能在下一次调用程序时使用,我们可以将数据保存到文件中(也就是硬盘),这样就可以做到数据的持久化了。

  注意:涉及到数据持久化的问题,我们一般持久化的方法有两种:1. 保存到硬盘上2. 保存到数据库中


二、什么是文件🍖

  文件是以硬盘为载体存储在计算机上的信息集合。在程序设计中我们一般谈的文件分为两种:程序文件数据文件是从功能的角度来分类的)。


2.1 程序文件🍖

  包含源程序文件后缀为.c)、目标文件后缀为.obj)、可执行文件后缀为.exe)。其中源文件就是存储我们所编写代码的文件,目标文件是由源文件经过编译(将.c文件转化成二进制文件的过程)后生成的,可执行文件是由目标文件经过链接就是将.obj文件与C语言提供的库函数连接起来的过程)后生成的。


2.2 数据文件🍖

  数据文件的内容不一定是程序,还有可能是程序运行时读写的数据。而本章主要讨论的就是这个数据文件,我们该怎么把数据写到文件中去,或者该怎么把数据从文件中读取到内存里面去。
在这里插入图片描述
  根据数据的存放形式,数据文件还可以被分为:文本文件二进制文件我们知道,数据在内存中是以二进制的形式存放的,若不加任何转换直接输出到文件中,那么就称为二进制文件。如果数据在存储前要进行转换,将数据转换成ASCII码的形式然后再存放到文件中,那么就称文本文件

  举个例子:int型变量10000以文本二进制的形式在文件中的内存布局,如下图所示。

在这里插入图片描述

  如若我们想查看文件中存储数据的二进制编码,我们把数据文件在VS编译器中打开,然后选择打开方式,接着选择二进制编译器,最后点击确定就可以查看了。
在这里插入图片描述


2.3 文件名🍖

  每一个文件都必然存在唯一的文件标识为了方便起见,文件标识通常被称为文件名),以便用户辨别和引用。

  每个文件名都是由三部分组成的:文件路径 + 文件名主干 + 文件后缀。举个例子:c:\code\test.txt,其中c:\code\是这个文件的路径,test是文件名主干,.txt是文件的后缀。

  那有人就要问了,为什么文件名一定要有路径呢? 那你想啊,你在C盘里放一个test.txt的文件,然后又在D盘中放一个test.txt的文件。那么问题来了,当我想要引用test.txt时,我到底是引用的C盘中的还是D盘中的呢?这就出现了歧义,所以为了能够使不同位置的文件名主干和后缀相同的文件有所区分,就必须在前面加上一个相对的路径。


三、文件的打开和关闭🍖

  值得注意的是,对文件操作的步骤应该是先打开文件,然后对文件进行,最后再关闭文件。那有人就要问了:为什么不直接对文件进行操作,而是需要先打开才行

  因为只有文件后我们才能与文件之间建立联系,才能对其进行修改,也可以这么说打开文件的目的是为了能够进行之后的读写操作。

  那为什么只有fopen打开文件后才能与文件之间建立联系? 因为每当使用fopen打开文件都会在内存中建立一个文件信息区,然后返回该区域的起始位置的地址(类型为FILE*类型,所以我们称之为文件指针)。之后我们就可以通过文件指针找到该信息区,又由于文件信息区与文件之间是紧密绑定的,故我们就可以通过文件信息区访问到该文件。也就是说,打开文件后返回的FILE*文件指针与文件之间建立了某种联系,使得我们通过文件指针就能找到与它关联的文件。关系图如下:

在这里插入图片描述

  至于“ 文件信息区 ”到底是什么,我之前有一篇博客讲述了,下面是它的链接【什么是文件信息区】。


3.1 fopen函数🍖

FILE *fopen( const char *filename, const char *mode );

  fopen第一个参数filename表示需要被打开的文件名(也就是一个字符串),第二个参数mode表示文件被打开模式(而打开的模式有很多种,如下图所示),返回值类型是一个FILE*类型的指针。注意:若打开文件失败,则返回空指针NULL,所以在打开文件后一定要检查一下返回的值。

在这里插入图片描述

  注意:

   1. 用'r'的形式打开文件后就只能对其进行读的操作,用'w'的形式打开文件后就只能对其进行写的操作。绝对不能出现用读的形式打开你在那卡卡写,用写的形式打开你在那卡卡读。

   2. 如果在读文件时我们想要打开的文件不存在,则表示打开失败返回NULL。但如果是在写或追加文件时我们想要打开的文件不存在,则会在相对路径底下新建一个文件。


3.2 fclose函数🍖

int fclose( FILE *stream );

  fclose的参数stream是想被关闭文件的文件指针,类型为FILE*。(我们会发现打开文件、读写文件、关闭文件的操作,与动态内存管理时的申请动态空间、使用动态空间、释放动态空间,这一整套操作非常相似。都会先占用内存一块空间,而这块空间又都不会自动释放,需要我们手动释放,若不释放则会一直占用这块资源,导致资源的浪费

  下面我们来实际运用fopenfclose来尝试打开和关闭文件。

#include<stdio.h>

int main()
{
	//打开文件(此时不存在test.txt文件)
	FILE* pf = fopen("test.txt", "r");
	//判断打开时是否发生错误
	if (pf == NULL)
	{
		//perror打印错误信息函数
		perror("fopen::");
		return 1;
	}

	//…

	//关闭文件
	fclose(pf);
	pf = NULL;
	printf("打开关闭文件成功\n");
	return 0;
}

在这里插入图片描述

  结果为:No such file or directory,意思是不存在这样一个文件。可如果我们在相对路径相对路径就是指:在当前目标项目的路径)底下给他建一个test.txt的文件,再来看一下结果。

在这里插入图片描述

  注意:参数filename可以是绝对路径的也可以是相对路径的。打开相对路径下的文件时,文件名前是不需要加文件的路径的,就如上面的test.txt就没有加路劲。而如果时访问绝对路径下的文件,则必须在文件名前加上文件的路径。下面举个例子,打开桌面上的test.txt文件。

在这里插入图片描述
在这里插入图片描述

  注意:在写文件的绝对路径时,字符串中的‘\’其实是转义字符,并不表示字符\,若像其表示\我们需要在为其转义一下,如上图所示。


四、文件读写🍖

4.1 文件的顺序读写🍖

  文件的顺序读写就是按照一定的顺序一个接着一个的对文件进行读写操作,而下面的这些都是顺序读写的函数。
在这里插入图片描述


4.1.1 按字符读和写【fgetc && fputc】🍖

int fputc( int c, FILE *stream );

  我们先来讲述fputc()字符输出函数,该函数可以向所有 “输出流” 输出数据,每次调用只能向流中写一个字符。fputc()函数有两个参数

  1. 参数int c想要写入的字符
  2. 参数FILE* stream表示想要向哪个文件输出,这是一个与文件关联的指针

  注意:fputc返回值int型的变量,若成功写入则返回每一个写入的字符,若写入失败则返回EOF

  下面让我们来实际操作一下:向文件中输出26个英文字母。

#include<stdio.h>

int main()
{
	//以写的方式打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//按字符写到文件中去
	int i = 0;
	for (i = 'a'; i <= 'z'; i++)
	{
		fputc(i, pf);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

  可以看到test.txt文件中有着从a到z的26个字母,而且是按照一个接着一个的顺序往文件里面放的,这就是顺序写。


int fgetc( FILE *stream );

  fgetc()字符输入函数,该函数适用于所有的“输入流”,可以从流中每次读取一个字符然后放到内存中去。fgetc()函数只有一个参数FILE *stream表示从哪一个文件中读取数据。至于读到的字符作为函数的返回值返回,类型为int

  下面来实际操作一下,接着从上一个test.txt的文件中读取数据(注意:此时文件中存放着26个英文字母):

#include<stdio.h>

int main()
{
	//以读的形式打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//按字符读取文件中的数据
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c", ch);
	}
	

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

  注意:如果文件中没什么数据可以被读取时,fgetc会返回EOF,我们可以以此为判断结束的标志。


4.1.2 按字符串读和写【fputs && fgets】🍖

  前面所说的fputc()fgetc()只能一个字符一个字符的读写,感觉效率有点低下,那是否存在一次性可以读写一整句话的函数呢?当然是存在的,fputs()fgets()就是这样的输入输出函数。

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

  fputs()文本行输出函数,该函数适用于所有“输出流”,可以一次性写一整个字符串到所要输出的或者文件中去。fputs()函数有两个参数

  1. 参数const char *string是一个指向需要写入的字符串的指针
  2. 参数FILE *stream与被写文件关联的指针

  函数fputs()返回值类型是int,若输出成功则返回一个非负值,若输出失败则返回EOF。下面来实际操作一下该函数:

#include<stdio.h>

int main()
{
	//以写的形式打开文件
	FILE* pf = fopen("test.txt", "w");

	//向内存中输出一个字符串
	fputs("hello world!!!", pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

  我们发现当我们以‘w’的形式打开文件后,那些原本就存在于文件中的内容会消失不见。其实这是向文件中写数据的一个特点,必然会在fopen打开文件时将文件中所有数据全部清空,然后再把我们所需要写的内容放进去。如果想要在原先存放的数组后添加新内存,我们可以以‘a’追加的形式打开文件。


char* fgets( char *string, int n, FILE *stream );

  fgets()文本行输入函数,该函数适用于所有“输入流”,可以从内存中读取字符串放到内存中去。fgets()函数有3个参数

  1. 参数char *string指向用于存放读取到的字符串的那块空间
  2. 参数int n最大读取个数
  3. 参数FILE *stream与被读文件关联的指针

  fgets()函数的返回值为一个char*类型的指针,若读取成功则返回读到字符串的起始地址,即:就是第一个参数指向那块空间的地址。若读取失败则返回NULL。下面来实际应用一下:

#include<stdio.h>

int main()
{
	//以读的形式打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	char arr[20] = { 0 };
	//从pf指向的文件中读一个长度为5的字符串到arr数组中
	fgets(arr, 5, pf);
	//将arr数组中存放的字符串打印出来
	printf("%s\n", arr);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

  我们发现打印结果与我们的预期不相符,按要求因该会一次性读取5个字符的内容,也就是“ hello ”这个字符串(现在test.txt文件中存放的内容是“ hello world!!!)。可实际上读到的却是“ hell ”,莫名其妙的少了一个字符,这是为什么呢?

  原因是:fgets()函数的第二个参数n表示你一次可以读n个字符,但正真读到字符数只有n-1个,因为最后一个位置是要留给字符串结束标志\0的。如下图所示:

在这里插入图片描述


4.1.3 格式化的读和写【fprintf && fscanf】🍖

  上面所述的fputcfgetcfputsfgets顺序读写函数仅适用于读写字符和字符串类型的数据,一旦要读写别的类型的数据时就不再适用了。所以为了能够向文件读写整型、浮点型、结构体等,C语言给出了fprintffscanf两个函数。

int fprintf( FILE *stream, const char *format [, argument ]…);

  fprintf()格式化输出函数,该函数适用于所有“输出流”,且用法与printf几乎一致,就是前面多出来个FILE*类型的参数,表示向什么文件输出。fprintf()返回值是写入的字符个数。下面来实际用一下该函数:

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	//以写的形式打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//向文件中输出一个结构体
	struct S s = { "zhangsan", 20, 67.5 };
	fprintf(pf, "%s %d %f", s.name, s.age, s.score);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述


int fscanf( FILE *stream, const char *format [, argument ]… );

  fscanf()格式化输入函数,该函数适用于所有的“输入流”,且用法与scanf几乎一致,就是前面多出来个FILE*类型的参数,表示从什么文件中读取数据。fscanf()的返回值是成功读取到数据的项数,若遇到文件结尾则返回EOF。下面来实际用一下该函数:

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	//以读的形式打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读取一个结构体类型的数据
	struct S s = { 0 };
	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
	printf("%s %d %f\n", s.name, s.age, s.score);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

  值得注意的是,在用fscanf()读取数据的时候,一定是大概知道文件中存放的是什么数据,以及这些数据的格式。尤其是具有某种特殊格式的文件,否则将无法下手。


4.1.4 以二进制的形式读和写【fwrite && fread】🍖

  我们发现不管是字符输入/输出函数文本行输入/输出函数还是格式化输入/输出函数操作的文件中存储的数据都是以文本的形式存在的,也就是以我们能够看懂的书面表达形式来存放。但fwrite()fread() 却是以二进制的形式写到文件里,再以二进制的形式读取出来,这就导致了我们无法读懂文件当中存放的到底是什么(因为文件是以文本的视角来看待文件中存放的数据的)。

  注意:前面所述的3对顺序读写函数是适用于所有“”的,也就是说这些函数可以对所有的外部设备进行操作。但fwrite()fread() 函数只能对“文件流”进行读写操作,这点要注意。

  注意:要使用fwrite()fread() 函数对文件进行读写操作,前提条件是必须以二进制读或者写的形式打开文件,即fopen的打开模式为wbrb

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

  fwrite()二进制输入函数,该函数具有4个参数:

  1. 参数const void *buffer指向要被写入文件的数据的指针
  2. 参数size_t size数据的大小
  3. 参数size_t count写入的数据的最大个数
  4. 参数FILE *stream与被写文件关联的指针

  fwrite()函数返回值为实际写入文件中数据的个数,如果发生错误返回值就会小于计数。下面来实际运用一下该函数:

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	//以二进制写的形式打开文件
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//将结构体以二进制的形式输出到文件中去
	struct S s = { "zhangsan", 20, 67.5 };
	fwrite(&s, sizeof(s), 1, pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

  可见将数据以二进制的形式写道文件中去,以文件的视角来开是一堆乱码。至于为什么姓名不是乱码呢,因为字符在内存中是以ASCII码的形式保存的,而文件也是以这种形式来看待的,所以不是乱码


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

  fread()二进制输入函数,该函数具有4个参数与fwrite一摸一样:

  1. 参数void *buffer指向存放被读取数据空间的指针
  2. 参数size_t size数据的大小
  3. 参数size_t count写入的数据的最大个数
  4. 参数FILE *stream与被读文件关联的指针

  fread()函数返回值 为实际读取到数据的个数,如果发生错误或在达到计数之前遇到文件末尾,则可能小于 count。下面来实际运用一下该函数:

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	//以二进制读的形式打开文件
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//从文件种以二进制的形式读取结构体数据
	struct S s = { 0 };
	fread(&s, sizeof(s), 1, pf);
	printf("%s %d %f\n", s.name, s.age, s.score);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述


4.2 文件的随机读写🍖

  根据上面对文件顺序读写的了解,我们发现顺序读写只能按照某种顺序一个接着一个的读或者写。但在C语言中还提供了一些随机读写的函数,如fseek()ftell()rewind()。它们能够让文件指针定位到我们想要的位置上去,从而做到想读哪就读哪。


4.2.1 fseek函数🍖

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

  该函数是通过参考位置位置偏移量来定位文件指针的。其中,参数long offset表示需要从参考位置处偏移的量,参数int origin表示参考位置。而fseek函数提供了三个参考位置:SEEK_SET(文件起始位置)、SEEK_END(文件末尾位置)、SEEK_CUR(文件指针当前位置)。下面举个例子:

#include<stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//偏移定位文件指针,相对于文件起始位置
	fseek(pf, 2, SEEK_SET);
	//读取字符
	int a = fgetc(pf);
	printf("%c\n", a);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
  注意:文件指针的偏移量的单位是字节,这道例题中SEEK_END(文件末尾位置)是指向字符f后一个字节,也就是说相对于末尾来说要定位f需要偏移-1个单位。


4.2.2 ftell函数🍖

long ftell( FILE *stream );

  ftell()函数返回当前文件指针相对于起始位置偏移量,参数是文件指针。下面来举个例子:

#include<stdio.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//偏移定位文件指针,相对于文件起始位置
	fseek(pf, 10, SEEK_SET);
	//打印当前文件指针相对于起始位置的偏移量
	int sz = ftell(pf);
	printf("%d", sz);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述


4.2.3 rewind函数🍖

void rewind( FILE *stream );

  rewind()函数可以让文件指针返回文件起始位置,参数是文件指针。下面来举个例子:

#include<stdio.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//偏移定位文件指针,相对于文件起始位置
	fseek(pf, 10, SEEK_SET);
	//打印当前文件指针相对于起始位置的偏移量
	int sz = ftell(pf);
	printf("%d\n", sz);
	//是文件指针返回文件起始位置
	rewind(pf);
	sz = ftell(pf);
	printf("%d\n", sz);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述


五、文件读取结束的判定🍖

   文本文件读取是否结束,判断返回值是否为EOFNULL

  1. 判断fgetc()返回值为EOF
  2. 判断fgets()返回值为NULL
  3. 判断fscanf()返回值为EOF

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

  1. 判断fwrite()返回值是否小于实际要读的个数

  下面举几个例子:

#include<stdio.h>

int main()
{
	int ch = 0;
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读取文件信息并判断是否结束
	while ((ch = fgetc(pf)) != EOF)
	{
		putchar(ch);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

#include<stdio.h>

int main()
{
	//写文件
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	FILE* pf = fopen("test.txt", "wb");
	fwrite(arr, sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), pf);
	fclose(pf);
	pf = NULL;
	//读文件
	int cover[10] = { 0 };
	int tmp = 0;
	int i = 0;
	pf = fopen("test.txt", "rb");
	while (1 == fread(&tmp, sizeof(cover[0]), 1, pf))
	{
		cover[i] = tmp;
		i++;
	}
	fclose(pf);
	pf = NULL;
	//打印数组cover中数
	for (i = 0; i < 10; i++)
	{
		printf("%d ", cover[i]);
	}
	return 0;
}

在这里插入图片描述


  注意:函数feof()并不是用来判断文件是否已经读取结束,而是应用于当文件读取结束时,判断到底是什么原因导致的,是读取失败还是遇到文件结尾了下面举个例子:

#include<stdio.h>

int main()
{
	//写文件
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	FILE* pf = fopen("test.txt", "wb");
	fwrite(arr, sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), pf);
	fclose(pf);
	pf = NULL;
	//读文件
	int cover[10] = { 0 };
	int i = 0;
	pf = fopen("test.txt", "rb");
	if (fread(cover, sizeof(cover[0]), 15, pf) == 15)
	{
		printf("成功读取数据\n");
		//打印数组cover中数
		for (i = 0; i < 10; i++)
		{
			printf("%d ", cover[i]);
		}
	}
	else
	{
		//判断是否是遇到文件末尾而结束
		if (feof(pf))
		{
			printf("End of file reached successfully");
		}
		else if (ferror(pf))
		{
			printf("I/O error when reading");
		}
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述


在这里插入图片描述

这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。

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

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

相关文章

React 入门:使用脚手架写一个Hello组件

文章目录本文目标开发前的准备编写主页面 index.html编写外壳组件 App.js编写入口文件 index.js代码组件化开发 Hello 组件开发 Welcome 组件引用组件组件化实现效果样式的模块化提升编码效率本文目标 通过使用脚手架确实让我们很方便的创建一个 React 项目基础代码结构&#…

力扣(LeetCode)11. 盛最多水的容器(C++)

双指针贪心 盛水的面积 长度 \times 左右柱子最低高度 area(r−l)min(height[l],height[r])area (r-l)\times min(height[l],height[r])area(r−l)min(height[l],height[r]) 初始时&#xff0c;我们不知道每个柱子的高度&#xff0c;但是我们可以选取最左侧柱子和最右侧柱子…

期望E与高斯分布的期望

目录 1. 期望定义 2. 期望性质 2.1 用期望定义方差 / 标准差 方差定义 标准差定义 方差的表示——离散型&#xff1a; 方差的表示——连续型&#xff1a; 方差的性质 3. (一元)高斯分布定义 4. (一元)高斯分布的性质 5. 二维随机向量的数学期望E与方差σ 参考 1. …

PyCharm安装部署(一) 百篇文章学PyQT

本文章是百篇文章学PyQT的第一篇&#xff0c;本文讲述如何安装PyCharm IDEA工具&#xff0c;其它工具也可以但是PyCharm 相对来说用的人多大家都认可(方案成熟)&#xff0c;pycharm是一款功能强大的python编辑器&#xff0c;具有跨平台性&#xff0c;本文介绍一下pycharm在wind…

SSM 医院在线挂号系统

SSM 医院在线挂号系统 SSM 医院在线挂号系统 功能介绍 首页 登录注册 图片轮播展示 系统简介 系统公告 医院介绍 医生展示 医院资讯 预约挂号 收藏 评论 在线留言 查看留言 后台管理 登录 管理员管理 修改密码 医院信息管理 医生信息管理 用户权限管理 科室信息管理 预约挂号…

微信小程序如何转云开发

微信小程序云开发&#xff0c;为前端全栈开发提供了很大的便利。本文主要介绍普通的微信小程序如何让转为云开发。 一、建cloudfunction文件夹 cloudfunction文件夹建立在小程序的根目录下。 二、修改 project.config.json配置 在 project.config.json文件中&#xff0c;添加&…

ip子网的划分方法

目录 1 子网划分的定义&#xff1a; 2 掩码介绍 3、子网划分要解决的问题&#xff1a; 4 子网划分步骤 5 范例1根据ip和掩码求子网和网络广播地址&#xff1a; 6 范例2根据ip和掩码求同网段地址 7 合并子网的例子根据ip范围合并&#xff0c;并添加回程路由&#xff1a; …

还不进来看吗?c趁你不注意偷偷将你的数据类型转换啦

前言 如果不了解 整形提升 的小伙伴可就要注意了,c偷偷将你的数据类型改变了你都不知道.快点和牛牛一起学习一下c语言中 整形提升的知识吧 ! 一、整形提升是什么&#xff0c;又是怎样提升的? 不知道小伙伴们有没有听过整形提升这个词? 整形提升是什么呢? C语言中,在进行…

[附源码]java毕业设计石林县石漠化信息查询分析系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【GlobalMapper精品教程】020:Lidar点云数据分类(自动分类、手动分类)案例详解

航测点云通常跟DSM一致,即包含植被、房屋等信息,必须进行点云分类、过滤,才能生成准确的高程点、等高线和DEM等地形数据。本文以案例的形式详细讲解globalmapper23中点云工具及使用方法。 文章目录 1. 点云分类2. 创建地面高程格网3. 地形绘制4. 格网转点云5. 点云抽稀6. 点…

面试:java中的各种锁

共享锁 共享锁有CountDownLatch, CyclicBarrier, Semaphore, ReentrantReadWriteLock等 ReadWriteLock&#xff0c;顾名思义&#xff0c;是读写锁。它维护了一对相关的锁 — — “读取锁”和“写入锁”&#xff0c;一个用于读取操作&#xff0c;另一个用于写入操作。“读取锁…

java计算机毕业设计ssm建设路小学芙童币和芙童印章管理系统

项目介绍 随着移动互联网技术的迅速发展,时代对人们的知识水平和综合素质要求也越来越高了,各种教育管理系统层出不穷。其中以建设路小学吉祥物“芙童”为卡通原型设计的芙童印章、芙童币深受学生和老师们的喜爱。这是学校结合德育教学、少先队活动和社会实践活动为他们量身定…

Mybatis源码解析(六):一级缓存和二级缓存的优先级

Mybatis源码系列文章 手写源码&#xff08;了解源码整体流程及重要组件&#xff09; Mybatis源码解析(一)&#xff1a;环境搭建 Mybatis源码解析(二)&#xff1a;全局配置文件的解析 Mybatis源码解析(三)&#xff1a;映射配置文件的解析 Mybatis源码解析(四)&#xff1a;s…

Unity学习笔记[一] RollBall小游戏

目录 一、适配vs 二、初识Unity 2.1 unity核心模块 2.2 Unity基本操作和场景操作 2.3 世界坐标系和局部坐标系 2.4 工具栏 QWER 三、基础知识 3.1 基本组件 3.2 刚体组件 3.2.1 获取刚体组件 3.2.2 给刚体施加力 3.3 三维向量Vector3 3.4 通过按键控制左右运动 3…

【Pygame】 游戏开发 基础知识

【Pygame】 第一课 游戏开发 基础知识概述Pygame 的安装Pygame 基础命令pygame.locals 模块pygame.init()pygame.display.set_mode()案例Pygame 显示文字pygame.font.Font()fill()render()blit()pygame.display.update()案例显示英文显示中文概述 Pygame 是一个跨平台的 Pytho…

计算机网络 - 物理层数据链路层大题复习题

文章目录1、在下面给出的TCP/IP层次模型图示中填写空缺处①-⑤的协议名称。2、请写出在OSI的第几层分别处理下面的问题&#xff1f;3、试简述数据链路层的三个基本问题为什么都必须加以解决&#xff1f;4、收发两端之间的传输距离为100km&#xff0c;信号在媒体上的传播速率为2…

网络层协议数据单元-N_PDU

诊断协议那些事儿 关联文章&#xff1a; UDS的OSI模型 ISO14229各Part介绍&#xff1a;第三部分&#xff1a;CAN实施的统一诊断服务&#xff08;UDSonCAN&#xff09; UDS诊断网络层ISO15765-2&#xff08;CAN&#xff09; 功能寻址的注意事项 文章目录诊断协议那些事儿一、N_…

雅思词汇真经单词共3663个

雅思词汇真经 / Vocabulary for IELTS / 学为贵 赢未来 / 英语真经派学习法 一本书精通雅思词汇 / 刘洪波 编著 / 涵盖&#xff1a;雅思必备核心词汇刘洪波老师原创雅思考点词库 逻辑词群记忆法&#xff0c;一群一群记单词&#xff0c;快速备考无负责 时尚插图&#xff0c;趣味…

Golang实现小型CMS内容管理功能(一):Gin框架搭配Gorm实现增删查改功能

我自己开发了一款在线客服系统&#xff0c;最近一直琢磨把客服系统官网做好。因为访客来的人不少&#xff0c;大部分人可能就是看看官网界面就走了&#xff0c;怎样把这些访客留存下来&#xff0c;去测试试用客服系统&#xff0c;是我一直琢磨的问题。 官网是一个企业的门面&a…

PyQT6 pip install (三) 百篇文章学PyQT

本文章是百篇文章学PyQT的第三篇&#xff0c;本文讲述如何使用PIP安装PyQT6&#xff0c;PyQT6在安装过程中会遇到很多问题&#xff0c;博主在本篇文章中将遇到和踩过的坑总结出来&#xff0c;可以供大家参考&#xff0c;希望大家安装顺利。包括 安装、遇到问题的解决方案、怎么…