【ONE·C || 文件操作】

news2024/11/15 12:35:23

总言

  C语言:文件操作。
  

文章目录

  • 总言
  • 1、文件是什么?为什么需要文件?
    • 1.1、为什么需要文件?
    • 1.2、文件是什么?
  • 2、文件的打开与关闭
    • 2.1、文件指针
    • 2.2、文件打开和关闭:fopen、fclose
    • 2.3、文件使用方式
  • 3、文件的顺序读写
    • 3.1、字符输入输出:fputc、fgetc
      • 3.1.1、fputc
      • 3.1.2、fgetc
    • 3.2、适用于所有流:stream的简单介绍
    • 3.3、文本输入输出:fputs、fgets
      • 3.3.1、fputs
      • 3.3.2、fgets
    • 3.4、格式化输入输出:fscanf、fprintf
      • 3.4.1、fprintf
      • 3.4.2、fscanf
    • 3.5、与字符串相关的输入输出:sscanf、sprintf
      • 3.5.1、对比说明
      • 3.5.2、使用介绍
    • 3.6、二进制输入输出:fread、fwrite
      • 3.6.1、fwrite
      • 3.6.2、fread
  • 4、文件的随机读写
    • 4.1、fseek
    • 4.2、ftell
    • 4.3、rewind
  • 5、其它相关内容
    • 5.1、文本文件和二进制文件
    • 5.2、文件读取结束判定
    • 5.3、文件缓冲区

  

1、文件是什么?为什么需要文件?

1.1、为什么需要文件?

  模拟实现通讯录时,会面临这样一个实际问题:在通讯录中把信息记录下来后,只有在我们自己选择删除数据的情况下,数据才不复存在,否则需要长久保留数据。
  这就涉及到了数据持久化的问题,一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据库等方式。使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。
  
  

1.2、文件是什么?

  1)、文件分类
  磁盘上的文件是文件。但在程序设计中,从文件功能的角度来看,一般文件有两种:程序文件、数据文件。
  程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
  数据文件: 文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
  
  
  2)、文件名称
  一个文件要有一个唯一的文件标识,以便用户识别和引用。为了方便起见,文件标识常被称为文件名
  文件名包含3部分:文件路径+文件名主干+文件后缀

D:\日常\TIM\Tencent Files\All Users\test.txt
文件路径:D:\日常\TIM\Tencent Files\All Users\
文件名主干:test
文件后缀:.txt

  
  
  

2、文件的打开与关闭

2.1、文件指针

  1)、文件指针是什么?

  缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
  每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE
在这里插入图片描述

  不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
  
  
  VS2019下FILE声明:

#ifndef _FILE_DEFINED
    #define _FILE_DEFINED
    typedef struct _iobuf
    {
        void* _Placeholder;
    } FILE;
#endif

  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结构的变量,这样使用起来更加方便。
在这里插入图片描述
  
  2)、文件指针的作用

  我们可以创建一个FILE*的指针变量,如下:

FILE* pf;

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

2.2、文件打开和关闭:fopen、fclose

  1)、fopen、fclose函数介绍
  相关函数链接:fopen
在这里插入图片描述

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

  const char * filename:所需要打开的文件名称。
  const char * mode:打开文件的方式,此处类型为字符指针,用于存放字符串首字符的地址。
  FILE *:在内存中创建一个与打开文件有关的文件信息区,同时返回一个文件指针,该指针指向文件信息区的起始地址(结构体)。
  NULL:如果文件打开失败,则返回空指针,同动态内存一致,需要进行判空操作,若错误则显示错误原因,并结束程序。
  
  
  相关链接:fclose
在这里插入图片描述

fclose
int fclose ( FILE * stream );

  FILE * stream:向指定要关闭的FILE指针
  
  
  2)、使用举例

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");//“r”此处为字符串,用双引号,r是一种文件读取模式
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	//……

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

	return 0;
}

  情形一:
在这里插入图片描述

  情形二:
在这里插入图片描述
  
  情形三:绝对路径与相对路径说明
  假如要打开的文件不在当前路径下,需要使用对应路径打开:
在这里插入图片描述
  
  
  

2.3、文件使用方式

  以下mode会在后续学习中慢慢用到。
在这里插入图片描述
  
  
  

3、文件的顺序读写

在这里插入图片描述

3.1、字符输入输出:fputc、fgetc

3.1.1、fputc

  相关函数链接:fputc
在这里插入图片描述

fputc
int fputc ( int character, FILE * stream );

  将字符character按顺序写入对应的文件流stream中,此处使用的是文件指针。如果失败则返回EOF。

  演示如下:

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写文件
	for (char ch = 'a'; ch <= 'z'; ch++)
	{
		fputc(ch, pf);
	}

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

	return 0;
}

在这里插入图片描述

  
  
  

3.1.2、fgetc

  相关函数链接:fgetc
在这里插入图片描述

fgetc
int fgetc ( FILE * stream );

  从对应的文件指针指向的文件中按顺序依次读取字符,若遇到文件结尾/错误则返回EOF,若成功则返回字符读取(提升为 int 值)。
  
  使用演示:

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写文件
	int ch;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c ", ch);
	}

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

	return 0;
}

在这里插入图片描述

  
  

3.2、适用于所有流:stream的简单介绍

  我们知道各种各样的外部设备,比如键盘、屏幕、U盘、硬盘、网卡等,数据信息的读写在它们之间进行交换,但不同的设备其读写方式可能存在差异,这样一来使用效率就会大幅降低,因为我们在做数据输入输出的前提是要学习了解它们的原理。因此,为了简化这一过程,我们在这些外设间引入一个中间商,即流,用于输入输出。这样一来,我们在各种数据交换时,就不必关心流与这些外设间是如何做到数据信息交换的,相当于一种封装。

在这里插入图片描述

  相关演示:

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

在这里插入图片描述
  
  
  

3.3、文本输入输出:fputs、fgets

3.3.1、fputs

  相关函数链接:fputs
在这里插入图片描述
  相关演示:

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写文件
	fputs("落霞与孤鹜齐飞,", pf);
	fputs("秋水共长天一色。\n", pf);

	fputs("渔舟唱晚,响穷彭蠡之滨;\n", pf);
	fputs("雁阵惊寒,声断衡阳之浦。\n", pf);


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

	return 0;
}

  可以看到,没加换行符,fputs会将当前内容放置于上此文尾,若加了换行符则另起一行。
在这里插入图片描述

  
  

3.3.2、fgets

  相关函数链接:fgets
在这里插入图片描述

  若成功,则返回str指针指向地址,若失败,则返回NULL;
  
  相关演示一:

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	char arr[255];

	//读写文件
	fgets(arr, 254, pf);
	printf("%s\n", arr);

	while (fgets(arr, 254, pf)!=NULL)
		printf("%s", arr);

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

	return 0;
}

在这里插入图片描述
  
  
  验证fgets会保留一位将\0放入:

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	char arr[10]="XXXXXXXXXX";

	//读写文件
	fgets(arr, 5, pf);
	printf("%s\n", arr);

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

	return 0;
}


在这里插入图片描述
  
  
  
  

3.4、格式化输入输出:fscanf、fprintf

3.4.1、fprintf

  相关函数链接:printf
在这里插入图片描述
  printf是将相关内容打印到标准输出,即屏幕上;
  fprintf适用于任意流,可将相关内容打印到指定的stream中。
  
  相关演示:

struct st
{
	char name[20];
	int age;
	double score;
};

int main()
{
	//创建一个学生数据,要求:将该学生数据的内容存入指定文件中
	struct st s1 = { "张三",25,98.00 };

	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写文件
	fprintf(pf,"%s %d %lf", s1.name, s1.age, s1.score);


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

	return 0;
}

在这里插入图片描述

  
  

3.4.2、fscanf

  相关函数链接:fscanf
在这里插入图片描述

  scanf是从标准输入流中读取数据,一般是键盘;
  fscanf适用于任意流,可从指定的流stream中读取数据。
  
  相关演示:

struct st
{
	char name[20];
	int age;
	double score;
};

int main()
{
	//创建一个学生数据,要求:从指定文件中读取相关数据信息填入该结构体中
	struct st s1 = {0};

	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写文件
	fscanf(pf, "%s %d %lf", s1.name, &(s1.age), &(s1.score));
	//注意,name为数组名,本身就是地址,故无需取地址操作符,其它二者读取时与scanf别无差异
	fprintf(stdout, "%s %d %lf", s1.name, s1.age, s1.score);


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

	return 0;
}

在这里插入图片描述

  
  
  

3.5、与字符串相关的输入输出:sscanf、sprintf

3.5.1、对比说明

  1)、scanf/printf、fscanf/fprintf、sscanf、sprintf对比说明

  scanf:针对标准输入输出流的格式化输入函数,Read formatted data from stdin
  printf:针对标准化输入输出流的格式化输出函数,Print formatted data to stdout

scanf
int scanf ( const char * format, ... );
printf
int printf ( const char * format, ... );

  
  fscanf:针对所有输入流的格式化输入函数,Read formatted data from stream
  fprintf:针对所有输出流的格式化输出函数,Write formatted data to stream

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

  
  sscanf:把一个字符串数据转换为格式化数据,Read formatted data from string
  sprintf:把一个格式化的数据转换为字符串数据,Write formatted data to string

sscanf
int sscanf ( const char * s, const char * format, ...);
sprintf
int sprintf ( char * str, const char * format, ... );

  
  

3.5.2、使用介绍

  相关函数链接:sprintf
在这里插入图片描述
  
  相关函数链接:sscanf
在这里插入图片描述

  
  使用举例:

struct st
{
	char name[20];
	int age;
	double score;
};

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写操作
	
	struct st s1 = { "李四",23,94.5 };//原数据
	struct st stof = { 0 };//未赋有效值的结构体:用于存放从字符串中转换过来的格式化数据
	char ftos[255];//字符数组:用于存放从格式化数据中转换得到的字符串

	//使用sprintf,将格式化数据转换成字符串
	sprintf(ftos, "%s %d %lf", s1.name, s1.age, s1.score);
	printf("ftos数组中:%s\n", ftos);

	//使用sscanf,将字符串转换为格式化数据
	sscanf(ftos, "%s %d %lf", stof.name, &(stof.age), &(stof.score));
	printf("stof结构体中:%s %d %lf\n", stof.name, stof.age, stof.score);

	

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

	return 0;
}

在这里插入图片描述
  
  
  

3.6、二进制输入输出:fread、fwrite

3.6.1、fwrite

  相关函数链接:fwrite
在这里插入图片描述
  注意理解该函数各参数含义,ptr是要写入的元素数组的指针,size是单个此类数据的大小(每个元素的大小),count是要写入这类数据的数目(元素个数),stream为指定输出的流。

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

  相关演示:

struct st
{
	char name[20];
	int age;
	double score;
};

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写操作
	
	struct st s1 = { "李四",23,94.5 };
	fwrite(&s1, sizeof(struct st), 1, pf);
	//含义:将s1中的数据输出至pf中,个数为1个,每个大小为sizeof(struct st)
	

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

	return 0;
}

  
在这里插入图片描述

  
  

3.6.2、fread

  相关函数链接:fread
在这里插入图片描述

  
  相关演示:

struct st
{
	char name[20];
	int age;
	double score;
};

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读写操作
	
	struct st s1 = { 0 };
	fread(&s1, sizeof(struct st), 1, pf);
	printf("%s %d %lf\n", s1.name, s1.age, s1.score);
	

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

	return 0;
}

在这里插入图片描述
  
  
  

4、文件的随机读写

4.1、fseek

  相关函数链接:fseek
  根据文件指针的位置和偏移量,重新定位文件指针。
在这里插入图片描述

SEEK_SET	Beginning of file
SEEK_CUR	Current position of the file pointer
SEEK_END	End of file *

  
  1)、关于随机位置读取


int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//文件读写
	//
	//文件中存储的例句:turn lemon into lemonade.
	for (int i = 0; i < 4; i++)
	{
		 printf("%c", fgetc(pf));//turn
	}
	printf("\n");
	//至此,文件指针指向trun lemon中的空白字符
	


	//演示一:以当前文件指针作为参考点
	fseek(pf, -1, SEEK_CUR);//当前指向turn中的n
	printf("文件向左偏移一位后:%c\n", fgetc(pf));//fgetc读取后后挪一位,到空白字符

	fseek(pf, 1, SEEK_CUR);//当前指向为lemon中的l
	printf("文件向右偏移一位后:%c\n", fgetc(pf));//fgetc读取后后挪一位,到e
	printf("\n");



	//演示二:以文件头作为参考点,此时偏移量不能为负数
	fseek(pf, 3, SEEK_SET);//当前指向trun中的n
	printf("文件向右偏移三位后:%c\n", fgetc(pf));
	printf("再次读取一位:%c\n", fgetc(pf));
	printf("\n");


	
	//演示三:以文件尾作为参考点,此时偏移量不能为正数
	fseek(pf, -3, SEEK_END);//当前指向为lemonade.中的d
	printf("文件向左偏移三位后:%c\n", fgetc(pf));
	printf("再次读取一位:%c\n", fgetc(pf));
	printf("\n");
	//

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

在这里插入图片描述

  
  
  2)、关于随机位置写入

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//文件读写
	//
	for (char ch = 'a'; ch <='z'; ch++)
	{
		fputc(ch,pf);
	}


	//演示一:以当前文件指针作为参考点
	fseek(pf, -22, SEEK_CUR);
	fputc('S', pf);


	//演示二:以文件头作为参考点,此时偏移量不能为负数
	fseek(pf, 6, SEEK_SET);
	fputc('O', pf);


	//演示三:以文件尾作为参考点,此时偏移量不能为正数
	fseek(pf, -3, SEEK_END);
	fputc('S', pf);

	//

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

在这里插入图片描述

  
  
  

4.2、ftell

  返回文件指针相对于起始位置的偏移量
  相关函数链接:ftell
  
  代码演示如下:

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//文件读写
	//
	for (char ch = 'a'; ch <='z'; ch++)
	{
		fputc(ch,pf);
	}

	fseek(pf, -22, SEEK_CUR);
	fputc('S', pf);

	long int pos = ftell(pf);
	printf("%ld\n", pos);
	//

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

在这里插入图片描述

  
  

4.3、rewind

  相关函数链接:rewind
  让文件指针的位置回到文件的起始位置
在这里插入图片描述

  相关演示:

int main()
{
	//打开文件
	FILE* pf = fopen("D:\\Daily\\test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//文件读写
	//
	for (char ch = 'a'; ch <='z'; ch++)
	{
		fputc(ch,pf);
	}

	fseek(pf, -22, SEEK_CUR);
	fputc('S', pf);

	long int pos = ftell(pf);
	printf("%ld\n", pos);

	rewind(pf);
	printf("%ld\n", ftell(pf));
	//

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

在这里插入图片描述
  
  
  
  

5、其它相关内容

5.1、文本文件和二进制文件

  1)、数据文件分类
  根据数据的组织形式,数据文件被称为文本文件或者二进制文件
  数据在内存中以二进制的形式存储,如果不加转换直接输出到外存,就是二进制文件。
  如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
在这里插入图片描述

  
  
  2)、数据在内存中的存储方式
  字符型数据一律以ASCII形式存储;
  数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
  
  

  3)、举例演示
  以整数10000为例子:
在这里插入图片描述
  
  一个测试代码:
  我们以二进制的形式将正数10000写入文件中

#include <stdio.h>
int main()
{
	int a = 10000;
	FILE* pf = fopen("D:\\Daily\\test.txt", "wb");
	fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
	fclose(pf);
	pf = NULL;
	return 0;
}

  假如用文本文件的形式打开,可以看到是乱码
在这里插入图片描述
  现在我们在VS中以二进制的形式打开,需要做一点设置,操作如下:
在这里插入图片描述
在这里插入图片描述

  
  
  
  

5.2、文件读取结束判定

  1)、关于feof函数说明
  在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。feof是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
在这里插入图片描述
  
  
  2)、关于文件读取结束说明
  根据文件类型的区别,判断文件读取结束具有一定区别:

  对文本文件读取是否结束,有两种判断方法:1、判断返回值是否为 EOF;2、判断返回值是否为 NULL 。
  例如:fgetc 函数中,判断文件读取结束是看是否返回 EOF,而fgets判断文件读取结束是看返回值是否为 NULL

  对二进制文件读取是否结束,可通过返回值是否小于实际要读的个数来判断。
  例如:fread判断返回值是否小于实际要读的个数。
  
  
  

5.3、文件缓冲区

  1)、什么是文件缓冲区
  ANSIC 标准采用“缓冲文件系统”处理的数据文件。所谓缓冲文件系统,是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。

  2)、为什么需要文件缓冲区
  文件缓冲区是一个链接内存与硬盘的过渡段,从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。之所以要这样做,是因为内存和硬盘处理数据的速度不一,若直接从磁盘中读取数据输送到内存, 会面临频繁访问、占用内存资源的现象。故而在二者之间搭建出一个中间商。
  需要注意的是,缓冲区的大小是根据C编译的系统来决定。
  
  
  
  
  

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

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

相关文章

windows下go安装并使用protobuf

go使用protobuf的过程以及可能出现的问题1. 下载proto windows版本并安装2. 安装protoc-gen-go3. proto文件转go文件报错protoc-gen-go: unable to determine go import path for "xxxx.proto"4. 生成的go文件中google.golang.org/protobuf/reflect/protoreflect依赖…

Zookeeper3.5.7版本——客户端命令行操作(znode 节点数据信息)

目录一、命令行语法二、znode 节点数据信息2.1、查看当前znode中所包含的内容2.2、查看当前节点详细数据2.3、节点详细数据解释一、命令行语法 命令行语法列表 命令基本语法功能描述help显示所有操作命令ls path使用 ls 命令来查看当前 znode 的子节点 [可监听]-w 监听子节点变…

粒子群优化最小二乘支持向量机SVM回归分析,pso-lssvm回归预测

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 SVM应用实例,粒子群优化最小二乘支持向量机SVM回归分析 代码 结果分析 展望 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大…

视觉SLAM十四讲ch6 非线性优化笔记

视觉SLAM十四讲ch6 非线性优化笔记本讲目标上讲回顾状态估计问题非线性最小二乘Gauss-Newton&#xff1a;高斯牛顿Levenburg-Marquadt&#xff1a;列文伯格-马夸尔特小结实践&#xff1a;CERES实践&#xff1a;G2O本讲目标 理解最小二乘法的含义和处理方式。 理解Gauss-Newton…

CopyOnWriteArrayList 源码解读

一、CopyOnWriteArrayList 源码解读 在 JUC 中&#xff0c;对于 ArrayList 的线程安全用法&#xff0c;比较推崇于使用 CopyOnWriteArrayList &#xff0c;那 CopyOnWriteArrayList是怎么解决线程安全问题的呢&#xff0c;本文带领大家一起解读下 CopyOnWriteArrayList 的源码…

Day908.joinsnljdist和group问题和备库自增主键问题 -MySQL实战

join&snlj&dist和group问题和备库自增主键问题 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于join&snlj&dist和group问题和备库自增主键问题的内容。 一、join 的写法 join 语句怎么优化&#xff1f;中&#xff0c;在介绍 join 执行顺序的时候&am…

基础复习第二十三天  File类与IO流的使用

java.io.File类:文件或文件目录路径的抽象表现形式&#xff0c;与平台无关。概述File能新建、删除、重命名文件或目录&#xff0c;但File不能访问文件内容本身。如果需要访问文件内容本身&#xff0c;则需要使用输入/输出流。想要在Java程序中表示一个真实存在的文件或目录&…

【Java并发编程】CountDownLatch

CountDownLatch是JUC提供的解决方案 CountDownLatch 可以保证一组子线程全部执行完牛后再进行主线程的执行操作。例如&#xff0c;主线程启动前&#xff0c;可能需要启动并执行若干子线程&#xff0c;这时就可以通过 CountDownLatch 来进行控制。 CountDownLatch是通过一个线程…

6. unity之脚本

1. 说明 当整个游戏运行起来之后&#xff0c;我们无法再借助鼠标来控制物体&#xff0c;此时可以使用脚本来更改物体的各种姿态&#xff0c;驱动游戏的整体运动逻辑。 2. 脚本添加 首先在Assets目录中&#xff0c;新创建一个Scripts文件夹&#xff0c;在该文件内右键鼠标选择…

opengl、opengl es、webgl介绍与opengl开发入门

1、OpenGL OpenGL&#xff08;英语&#xff1a;Open Graphics Library&#xff0c;译名&#xff1a;开放图形库或者“开放式图形库”&#xff09;常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。OpenGL的高效实现&#xff08;利用了图形加速硬件&#xff09;存在于Windo…

HCIP-5OSPF区域类型学习笔记

1、OSPF区域类型 OSPF提出了区域的概念&#xff08;AREA&#xff09;&#xff0c;区域是将所有运行OSPF 的路由器人为的分成不同的组&#xff0c;以区域ID来标示。在区域内路由计算的方法不变&#xff0c;由于划分区域之后&#xff0c;每个区域内的路由器不会很多&#xff0c;…

【Python从入门到进阶】10、流程控制语句-循环语句(for-while)

接上篇《9、流程控制语句-条件语句(if-else)》 上一篇我们学习了Python的控制流语句的概念&#xff0c;以及其中的条件语句(if/else)&#xff0c;本篇我们来学习控制流语句中的循环语句(for/while)。 一、Python中的循环 Python的循环结构就是让程序“杀个回马枪”&#xff0…

修复电子管

年前在咸鱼捡漏买到了10根1G4G电子管&#xff0c;这是一种直热三极管&#xff0c;非常的少见。买回来的时候所有的灯丝都是通的&#xff0c;卖家说都是新的&#xff0c;库存货&#xff0c;但是外观实在是太糟糕了&#xff0c;看着就像被埋在垃圾场埋了几十年的那种&#xff0c;…

ECharts可视化库--常用组件

目录 一.series系列 二.常见组件 1.标题title 2.图例legend 3.工具栏toolbox 4.提示框tooltip 5.坐标轴 xAxis yAsix 6.series系列 上一篇已经介绍了ECharts库的导入工作和绘制基本的图标&#xff0c;今天我们来了解一下常用的组件&#xff0c;如果对数据可视化感兴…

嵌入式安防监控项目——前期知识复习

目录 一、概述 二、C语言 三、数据结构 四、IO进程 五、网络 六、ARM体系结构和接口技术 七、系统移植 八、内核驱动 一、概述 我再报班之前学过51和32&#xff0c;不过都是自学的。报班开始先从应用层入手的&#xff0c;C语言和数据结构。只要是个IT专业的大学这都是必…

【剑指Offer】JZ14--剪绳子

剪绳子详解1.问题描述2.解题思路3.具体实现1.问题描述 2.解题思路 首先想到的思路&#xff1a;因为是求乘积的最大值&#xff0c;所以如果截取剩下的是1&#xff0c;那还是它本身就没有意义。从此出发&#xff0c;考虑绳子长度是2、3、4、5…通过穷举法来找规律。 值–》拆分–…

Keychron K7 Pro 轻薄矮轴机械键盘开箱体验

文章目录1. 拆箱2. 零件3. 外观4. 声音5. 特点5.1 有线 / 无线5.2 RGB背光5.3 轻薄5.4 mac / win / iphone 切换5.5 人体工程学支持5.6 扁平双射PBT键帽5.7 重新设计的稳定器5.8 扁平Gateron(佳达隆)轴体5.9 热插拔5.10 支持 QMK / VIA 改键6. 对比6.1 K7 与 K7 Pro 参数对比6.…

Windows10下使用CMake编译ITK5.2.1步骤

编译环境&#xff1a;Windows10VS2017Cmak3.24.0ITK5.2.1 编译步骤&#xff1a; 1、下载ITK到本地&#xff1a;ITK官网Download | ITK&#xff0c;ITK5.2.1下载地址 https://github.com/InsightSoftwareConsortium/ITK/releases/download/v5.2.1/InsightToolkit-5.2.1.zip ​…

13_pinctrl子系统

总结 pinctrl作为驱动 iomuxc节点在设备树里面 存储全部所需的引脚配置信息 iomux节点匹配pinctrl子系统 控制硬件外设的时候 要知道有哪些gpio 再看gpio有哪些服用寄存器 接着在程序配置gpio相关寄存器 这样搞效率很低 所以用iomux节点保存所有的引脚组 pinctrl驱动起来的时…

Linux(基于 Centos7) 常用操作

1.Linux 简介Linux 是一种 免费使用、自由传播的类 Unix 操作系统Linux操作系统内核&#xff0c;由林纳斯托瓦兹在1991年10月5日首次发布...Linux 是一套开源操作系统&#xff0c;它有稳定、消耗资源小、安全性高等特点大多数人都是直接使用 Linux 发行版&#xff08;就是将 Li…