C语言——如何进行文件操作

news2024/9/23 19:21:02

大家好,我是残念,希望在你看完之后,能对你有所帮助,有什么不足请指正!共同学习交流
本文由:残念ing原创CSDN首发,如需要转载请通知
个人主页:残念ing-CSDN博客,欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:残念ing 的C语言系列专栏——CSDN博客
 

 这是一篇关于文件操作的文章,前面的文章会比较多,但是不用担心,我已经为你们总结好了。还有关键例子来助力你理解。话不多说,我们现在开始!!!!(建议使用电脑观看哦)

目录

前言:为什么要使用文件?????

1.那什么是文件呢???

1.1 文件名

2. 什么是二进制文件和文本文件?

3. 文件的打开和关闭

3.1 流和标准流

3.1.1 流(中间商)

3.1.2 标准流

3.2 文件指针

3.3 文件的打开和关闭

4. 文件的顺序读写

4.1 顺序读写函数介绍

4.2 对比⼀组函数:

5. 文件的随机读写

5.1 fseek

5.2 ftell

5.3 rewind

6. 文件读取结束的判定

6.1 被错误使用的 feof

7. 文件缓冲区


前言:为什么要使用文件?????

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

本次学习的是数据文件。在之前我们所以的处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件。

1.那什么是文件呢???

其实磁盘上的文件就是文件。但是在程序设计中,我们一般的文件有两种:程序文件,数据文件(从文件功能的角度来分类的 )。

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

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

1.1 文件名

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

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

例如:D:\code\test.txt

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

2. 什么是二进制文件和文本文件?

根据数据的组织形式,数据文件被称为文本文件或者二进制文件

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

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

有个疑问:一个数据在内存中是怎么存储的呢?

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

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

测试代码:

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

 10000在二进制文件中

 

3. 文件的打开和关闭

3.1 流和标准流

3.1.1 流(中间商)

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

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

一般情况下,我们要向流中写数据,或者从流中读取数据,都是要打开流,然后操作。

3.1.2 标准流

我们会发现我们从键盘输入数据,向屏幕上输出数据,并没有发现有流打开。

其实C语音程序在启动的时候,就默认打开了3个流:

stdin——标准输入流,在大多数的环境中从键盘输入,scanf函数就是从标准输入流中读取数据。

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

stderr——标准错误流,大多数环境中输出到显示器界面。

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

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

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

3.2 文件指针

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

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

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

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

注意:不同的C编译器的FILE类型包括的内容不完全相同,但是大同小异。

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并且填充其中的信息,使用者不关心细节。

一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

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

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

 

3.3 文件的打开和关闭

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

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

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

//打开⽂件
FILE * fopen ( const char * filename, const char * mode );
                              文件名                打开方式
//关闭⽂件
int fclose ( FILE * stream );

mode 表示文件的打开模式,下面都是文件的打开模式:

例如:

//   . 表示当前目录
//  .. 表示上一级路径
//FILE* p=fopen("./../data.txt", "w");./../--相对路径
//FILE* p=fopen("c:\\dast\\1\\data.txt","r");\\...\\\...\\绝对路径
int main()
{
	//打开文件,为了写
	FILE* p=fopen("data.txt", "w");//没有文件时新建一个,有文件并且里面有内容,会清空文件内容
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	
	//关闭文件
	fclose(p);
	p = NULL;
	return 0;
}

4. 文件的顺序读写

4.1 顺序读写函数介绍

上⾯说的适用于所有输⼊流⼀般指适⽤于标准输⼊流和其他输⼊流(如⽂件输⼊流);所有输出流⼀般指适用于标准输出流和其他输出流(如⽂件输出流)

例如:

int main()
{
	//打开文件,为了写
	FILE* p = fopen("data.txt", "r");//写用w,读用r
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	//fputc('a', p);
	//fputc('b', p);
	//fputc('c', p);
	//fputc('d', p);
	//for (int i = 0; i < 26; i++)
	//{
	//	fputc('a' + i, p);
	//	fputc('a' + i, stdout);//stdout--关联到屏幕的标准输出流
	//	fputc('\n', p);
	//}
	//读文件
	int ch = fgetc(p);
	printf("%c ", ch);
	ch = fgetc(p);
	printf("%c ", ch);
	ch = fgetc(p);
	printf("%c ", ch);
	//关闭文件
	fclose(p);
	p = NULL;
	return 0;
}

 fputs 举例:

//fputs---写一串字符串进去文件里
int main()
{
	FILE* p3 = fopen("data.txt", "w");
	if (p3 == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写入
	fputs("abcdef\n", p3);
	fputs("abcdef\n", p3);
	
	fclose(p3);
	p3 = NULL;
	return 0;
}

fgets 举例:

//fputs---写一串字符串进去文件里
int main()
{
	FILE* p3 = fopen("data.txt", "w");
	if (p3 == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读取
	char arr[20];
	fgets(arr, 10, p3);
	//char* fgets(char* str,int num,FILE*stream)---只会读num-1个字符,放在str中;
	//字符最后为\0;
	fclose(p3);
	p3 = NULL;
	return 0;
}

 fprintf 举例:

//fprintf---可变参数变量
struct str
{
	char name[20];
	int eage;
	float score;
};
int main()
{
	struct str s = { "zhangsan",100,100.0f };
	struct str t = { 0 };
	FILE* p = fopen("data3.txt", "w");
	if (p == NULL)
	{
		perror("p");
		return 1;
	}
	//写文件
	fprintf(p, "%s %d %f", s.name, s.eage, s.score);

	fclose(p);
	p = NULL;
	return 0;
}

fscanf 举例:

struct str
{
	char name[20];
	int eage;
	float score;
};
int main()
{
	struct str s = { "zhangsan",100,100.0f };
	struct str t = { 0 };
	FILE* p = fopen("data3.txt", "r");
	if (p == NULL)
	{
		perror("p");
		return 1;
	}
	//写读文件
	fscanf(p, "%s %d %f", t.name, &(t.eage), &(t.score));
	fprintf(stdout, "%s %d %f", t.name, t.eage, t.score);
	fclose(p);
	p = NULL;
	return 0;
}

fwrite 举例:

struct str
{
	char name[20];
	int eage;
	float score;
};
int main()
{
	struct str s = { "zhangsan",100,100.0f };
	struct str t = {0};
	FILE* p = fopen("data5.txt", "wb");
	if (p == NULL)
	{
		perror("p");
		return 1;
	}
	//以二进制的方式写文件
	fwrite(&s,sizeof(s),1,p);
	fclose(p);
	p = NULL;
	return 0;
}

fread 举例: 

struct str
{
	char name[20];
	int eage;
	float score;
};
int main()
{
	struct str s = { "zhangsan",100,100.0f };
	struct str t = {0};
	FILE* p = fopen("data5.txt", "r");
	if (p == NULL)
	{
		perror("p");
		return 1;
	}
	//以二进制的方式读文件
	fread(&t, sizeof(t), 1, p);
	printf( "%s %d %f", t.name, t.eage, t.score);
	fclose(p);
	p = NULL;
	return 0;
}

4.2 对比⼀组函数:

scanf/fscanf/sscanf

printf/fprintf/sprintf

scanf --针对标准输入(键盘)的格式化输入函数

printf--针对标准输出流(屏幕)的格式化输出函数

fscanf--针对所有输入流的格式化输入函数

fprintf--针对所有输出流的格式化输出函数

sscanf--从一个字符串中读取一个格式化的数据

sprintf--把一个格式化的数据转换成字符串

举例:

struct s
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct s a = { "zhangsan",10,100 };
	char arr[100];
	sprintf(arr,"%s %d %f", a.name, a.age, a.score);//把结构体中的数据存放在字符数组中
	printf("%s\n", arr);
	struct s b = { 0 };
	sscanf(arr, "%s %d %f", b.name, &(b.age), &(b.score));//把字符数组中的数据读取出来存到结构体b中
	printf("%s %d %f\n", b.name, b.age, b.score);
	return 0;
}

5. 文件的随机读写

5.1 fseek

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

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

例子

//文件的随机读写
//fseek--根据文件内容的光标进行读写
//int fseek(FILE* stream,long int offset,int origin);
//origin有三种选择
//1. SEEK_SET--从起始位置开始
//2. SEEK_CUR--从当前光标位置开始
//3. SEEK_END--从最后一位开始
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
	 ch = fgetc(pf);
	printf("%c\n", ch);
	 ch = fgetc(pf);
	printf("%c\n", ch);
	fseek(pf, -3, SEEK_CUR);
	 ch = fgetc(pf);
	printf("%c\n", ch);
	return 0;
}

5.2 ftell

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

long int ftell ( FILE * stream );

例子:

//ftell--放回的是文件指针相对于起始位置的偏移量

int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	int n = ftell(pf);
	printf("%d\n", n);
	fseek(pf, -n, SEEK_CUR);
	ch = fgetc(pf);
	printf("%c\n", ch);
	return 0;
}

5.3 rewind

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

void rewind ( FILE * stream );

例子:

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

int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	rewind(pf);//让文件指针回到文件起始位置
	ch = fgetc(pf);
	printf("%c\n", ch);
	return 0;
}

6. 文件读取结束的判定

6.1 被错误使用的 feof

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

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

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

例如:
fgetc 判断是否为EOF

fgetc 判断返回值是否为 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);
}

7. 文件缓冲区

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

#include <stdio.h>
#include <windows.h>
//VS2019 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/1421030.html

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

相关文章

C语言探索:水仙花数的奥秘与计算

摘要&#xff1a; 水仙花数&#xff0c;一种特殊的三位数&#xff0c;其各位数字的立方和等于该数本身。本文将详细介绍水仙花数的定义、性质&#xff0c;以及如何使用C语言来寻找100至999范围内的水仙花数。 目录 一、水仙花数的定义与性质 二、用C语言寻找100至999范围内的…

AJAX的原理(重点)

◆ XMLHttpRequest 什么是XMLHttpRequest&#xff1f; 定义&#xff1a; 关系&#xff1a;axios 内部采用 XMLHttpRequest 与服务器交互 注意&#xff1a;直白点说就是axios内部就是封装了XMLHttpRequest这个对象来实现发送异步请求的 使用 XMLHttpRequest 步骤&#xff1a…

聊聊用户故事地图

这是鼎叔的第八十五篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本专栏和微信公众号《敏捷测试转型》&#xff0c;星标收藏&#xff0c;大量原创思考文章陆续推出。本人新书《无测试组织-测试团队的敏捷转型》已出版&#xff08;机械工业出版社&…

npm安装下载修改镜像源

问题描述一 npm install 时&#xff0c;报错&#xff1a;npm ERR! network request to https://registry.npmjs.org/postcss-pxtorem failed, reason: connect ETIMEDOU&#xff0c;这是因为默认npm安装会请求国外的镜像源&#xff0c;导致下载缓慢容易断开请求下载失败的 np…

第九节HarmonyOS 常用基础组件18-checkBox

1、描述 提供多选框组件&#xff0c;通常用于某选项的打开或关闭。 2、接口 Checkbox(options:{name?: string, group?: string}) 3、参数 参数名 参数类型 必填 描述 name string 否 多选框名称 group string 否 多选框群组名称。&#xff08;未配合使用Chec…

Coppeliasim倒立摆demo

首先需要将使用Python远程控制的文件导入到文件夹&#xff0c;核心是深蓝色的三个文件。 本版本为4.70&#xff0c;其文件所在位置如下图所示&#xff0c;需要注意的是&#xff0c;目前不支持Ubuntu22的远程api&#xff1a; 双击Sphere这一行的灰色文件&#xff0c;可以看到远程…

【C++版】排序算法详解

目录 直接插入排序 希尔排序 选择排序 冒泡排序 堆排序 快速排序 hoare法 挖坑法 前后指针法 非递归版本 快速排序中的优化 归并排序 递归版本 非递归版本 计数排序 总结 直接插入排序 直接插入排序的思想是&#xff1a;把待排序的记录按其关键码值的大小逐个插入…

ICMP——网际控制报文协议

目录 1.1 网际控制报文协议 ICMP 1.2 ICMP 报文的格式 1.2.1 ICMP 报文的种类 ICMP 差错报告报文 ICMP 询问报文 1.3 ICMP 的应用 1.4 ICMP抓包 1.4.1 ICMP请求包&#xff08;request&#xff09; 1.4.2 ICMP应答包&#xff08;reply&#xff09; 1.1 网际控制报文协议…

解决maven 在IDEA 下载依赖包速度慢的问题

1.idea界面双击shift键 2.打开setting.xml文件 复制粘贴 <?xml version"1.0" encoding"UTF-8"?> <settings xmlns"http://maven.apache.org/SETTINGS/1.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sc…

Spring AOP实现

Spring AOP实现 AOP概述什么是AOP什么是Spring AOP Spring AOP快速入门引入依赖实现计时器 Spring AOP详解Spring AOP核心概念切点(Pointcut)连接点(Join Point)通知(Advice)切面(Aspect) 通知类型注意事项 PointCut多个切面切面优先级 Order切点表达式execution表达式annotati…

【开源】基于JAVA的就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

双链表的基本知识以及增删查改的实现

满怀热忱&#xff0c;前往梦的彼岸 前言 之前我们对单链表进行了非常细致的剖析&#xff0c;现在我们所面临的则是与之相对应的双链表&#xff0c;我会先告诉诸位它的基本知识&#xff0c;再接着把它的增删查改讲一下&#xff0c;ok&#xff0c;正文开始。 一.链表的种类 我…

07.领域驱动设计:掌握整洁架构、六边形架构以及3种常见微服务架构模型的对比和分析

目录 1、概述 2、整洁架构 3、六边形架构 4、三种微服务架构模型的对比和分析 5、从三种架构模型看中台和微服务设计 5.1 中台建设要聚焦领域模型 5.2 微服务要有合理的架构分层 5.2.1 项目级微服务 5.2.2 企业级中台微服务 5.3 应用和资源的解耦与适配 6、总结 1、概…

三步万能公式解决软件各种打不开异常

程序员都知道,辛苦做的软件发给客户打不开那是一个大写的尴尬,尴尬归尴尬还是要想办法解决问题. 第一步清理环境. 目标机台有环境和没有运行环境的,统统把vs环境卸载了,让目标机台缺少环境.第二步打包环境 源代码添加打包工程,setup,重新编译.![添加setup ](https://img-blo…

LeetCode——415. 字符串相加

C开头 &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️Take your time ! &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#…

【架构论文】SCALE: Secure and Scalable Cache Partitioning(2023 HOST)

SCALE: Secure and Scalable Cache Partitioning 摘要 LLC可以提高性能&#xff0c;但是会引入安全漏洞&#xff0c;缓存分配的可预测变化可以充当侧信道&#xff0c;提出了一种安全的缓存分配策略&#xff0c;保护缓存免受基于时间的侧信道攻击。SCALE使用随机性实现动态可扩…

AI大模型专题:2024大模型安全流通平台市场厂商评估报告

今天分享的是AI大模型系列深度研究报告&#xff1a;《AI大模型专题&#xff1a;2024大模型安全流通平台市场厂商评估报告》。 &#xff08;报告出品方&#xff1a;揽睿星舟&#xff09; 报告共计&#xff1a;22页 大模型安全流通平台市场分析 企业需要大模型安全流通平台覆盖…

C语言 开发篇+一个简单的数据库管理系统ZDB

说明&#xff1a;本文供数据库爱好者和初级开发人员学习使用 标签&#xff1a;数据库管理系统、RDBMS、C语言小程序、C语言、C程序 系统&#xff1a;Windows 11 x86 CPU &#xff1a;Intel IDE &#xff1a;CLion 语言&#xff1a;C语言 标准&#xff1a;C23 提示&#xff1a;如…

C语言用SHBrowseForFolder弹出选择文件夹的对话框

【程序运行效果】 【程序代码】 main.c&#xff1a; #define COBJMACROS #include <stdio.h> #include <tchar.h> #include <Windows.h> #include <windowsx.h> #include <CommCtrl.h> #include <ShlObj.h> #include "resource.h&q…

JVM-类的生命周期

类的生命周期概述 类的生命周期描述了一个类加载、使用、卸载的整个过程。整体可以分为&#xff1a; 加载 连接&#xff0c;其中又分为验证、准备、解析三个子阶段 初始化 使用 卸载 加载阶段 加载(Loading)阶段第一步是类加载器根据类的全限定名通过不同的渠道以二进制流的方…