【C语言】内存管理内存管理函数文件管理文件管理函数

news2024/9/26 5:12:57

主页:醋溜马桶圈-CSDN博客

专栏:C语言_醋溜马桶圈的博客-CSDN博客

gitee:mnxcc (mnxcc) - Gitee.com

目录

1.C/C++程序的内存开辟

2.内存相关的函数

2.1 memcpy

2.1.1 memcpy函数的使用

2.1.2 memcpy函数的模拟实现

2.2 memmove

2.2.2 memcpy存在的局限性

2.2.2 memmove函数的使用

2.2.3 memmove函数的模拟实现

2.3 memset

2.3.1 memset函数的使用

2.4 memcmp

2.4.1 memcpy函数的使用

3.动态内存管理

3.1 为什么存在动态内存分配?

3.2 动态内存函数的介绍

3.2.1 malloc

3.2.2 calloc

3.2.3 realloc

3.3 常见的动态内存错误

3.3.1 对NULL指针的解引用操作

3.3.2 对非动态开辟内存使用free释放

3.3.3 使用free释放一块动态开辟内存的一部分

3.3.4 对同一块动态内存多次释放 

3.3.5 动态开辟内存忘记释放(内存泄漏) 

4.C语言文件操作

4.1 为什么使用文件

4.2 什么是文件

4.2.1 程序文件

4.2.2 数据文件

4.2.3 文件名 

4.3 文件的打开和关闭

4.3.1 文件指针

4.3.2 文件的打开和关闭 

4.3.3 fopen函数

4.3.4 fclose函数

4.4 文件的顺序读写

4.4.1 顺序读写函数介绍

fgetc和fputc函数

4.4.2 输入流和输出流

4.4.3 对比一组函数

4.5 文件的随机读写

4.5.1 fseek函数

4.5.2 ftell函数 

4.5.3 rewind函数 

4.6 文本文件和二进制文件

4.7 文件读取结束的判定

4.7.1 被错误使用的feof

4.7.2 fread函数

4.8 文件缓冲区


1.C/C++程序的内存开辟

前面我们说过,计算机中内存分为三个区域:栈区,堆区,静态区

但是这只是个简化的版本,接下来我们仔细看看内存区域的划分

 C/C++程序内存分配的几个区域:

  1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。栈区主要存放运行函数而分配的局部变量,函数参数、返回数据、返回地址等
  2. 堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。分配方式类似于链表
  3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放
  4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码

实际上普通的局部变量是在栈区分配空间的,栈区的特点时在上面创建的变量出了作用域就销毁

但是被static修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁,所以生命周期变长

2.内存相关的函数

2.1 memcpy

2.1.1 memcpy函数的使用

strcpy函数我们可能都知道,字符串拷贝函数,跟函数名一样,只能拷贝字符串

但是我们知道,内存中的数据不仅仅是字符

int arr1[10] = { 0 };
int arr2[] = { 1,2,3,4,5 };

比如,当我们有这么一段数据

我们需要把arr2中的前五个整型的数据拷贝放在arr1中 

这个时候我们就不能使用strcpy,因为他是整型数据了

这时候我们C语言就提供了memcpy函数,同样的,我们在Reference - C++ Reference (cplusplus.com)上学习一下该函数

void * memcpy ( void * destination, const void * source, size_t num );

 我们可以理解为,把source中的前num个字节的数据拷贝放到destination中去

我们还是用监视窗口来看一下数据是否被拷贝

我们可以看到确实是被拷贝过去了 

2.1.2 memcpy函数的模拟实现

void* my_memcpy(const void* dest, const void* src, size_t sz)
{
	assert(dest && src);
	while (sz--)
	{
		*(char*)dest = *(char*)src;
		dest=(char*)dest+1;
		src=(char*)src+1;
	}
}

运行的结果也是同样的效果

这里我们要注意

void*是不能直接++和--的,所以我们需要强转为char*类型,++或--跳过一个字节的空间

void*是不能直接解引用的,所以我们需要强转为char*类型,解引用

2.2 memmove

2.2.2 memcpy存在的局限性

我们这个代码也是存在一定的局限性,比如下面这种情况

将数组arr的前五个数据拷贝到arr[2]的位置,通过调试我们发现写出来的函数并不能有效的实现

C语言的标准规定:

不重叠内存的拷贝,可以使用memcpy,重叠内存的拷贝就不能使用了

重叠内存的拷贝,我们可以使用memmove函数来实现 

2.2.2 memmove函数的使用

同样的,我们来先学习一下memmove函数的使用

void * memmove ( void * destination, const void * source, size_t num );

他的参数和返回类型和memcpy一模一样,

我们尝试使用一下memmove函数,看能否解决刚才的问题

这样问题就很好的解决了 

2.2.3 memmove函数的模拟实现

#include <stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(const void* dest, const void* src, size_t sz)
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src)
	{
		//前->后
		for(int i=0;i<sz;i++)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (sz--)
		{
			*((char*)dest + sz) = *((char*)src+sz);
			/*dest = (char*)dest - 1;
			src = (char*)src - 1;*/
		}
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1+2, arr1, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
	my_memmove(arr2 , arr2+2, 20);
	for (int j = 0; j < 10; j++)
	{
		printf("%d ", arr2[j]);
	}
	return 0;
}

 这样我们的代码就能实现memmove的效果了

2.3 memset

2.3.1 memset函数的使用

void * memset ( void * ptr, int value, size_t num );

memset函数是以字节为单位设置内存的函数 

将 ptr 指向的内存块第1个字节(num)设置为指定(value)

举个例子

2.4 memcmp

2.4.1 memcpy函数的使用

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

memcmp函数作用是比较ptr1和ptr2指向的内存空间的前num个字节的数据

  • 如果相同则返回0
  • 如果ptr1指向内存的数据是小于ptr2指向内存的数据的,则返回小于0的数字
  • 否则返回大于0的数字

memcmp比较是以字节为单位比较的

举个例子

3.动态内存管理

3.1 为什么存在动态内存分配?

2种申请内存的方式:

  1. 一次开辟一个变量的空间
  2. 一次开辟一个数组的空间
int main()
{
    int a = 10;//存放一个值
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//存放一组值
    return 0;
}

但是他们都存在一个问题:空间一旦申请好,大小就是固定的,不能改变

所以C语言给了我们一种权利,能够动态申请和管理内存空间

3.2 动态内存函数的介绍

3.2.1 malloc

C语言提供了一个能够动态内存开辟的函数:

void* malloc(size_t size);

我们可以在cplusplus网站来查看一下这个函数:

malloc - C++ Reference (cplusplus.com)

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针

  • 如果开辟成功,则返回一个指向开辟好空间的指针
  • 如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查
  • 返回值的类型是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定
  • 如果参数size为0,malloc的行为的标准是未定义的,取决于编译器

那么怎么使用这个函数呢,我们举个例子;

malloc需要包含的头文件是stdlib.h

如果申请失败就会这样:

如果返回了NULL指针,则不能使用了

​​​​​​

从这个图可以看出

动态内存的管理都是在堆区进行的 

假设我们要使用这块内存

malloc申请的空间是怎么释放的呢?

  1. free释放,主动释放
  2. 程序退出后,malloc申请的空间,也会被操作系统回收的 

free

malloc函数是用来申请空间的,这块空间使用完之后还是需要释放

C语言中提供了另外一个函数free,专门是用来做动态内存的释放和回收的,函数原型如下:

void free(void* ptr);

同样我们先认识一下这个函数free - C++ Reference (cplusplus.com)

free函数用来释放动态开辟的内存

  • 如果参数ptr指向的空间不是动态开辟的,那free函数的行为是未定义的
  • 如果参数ptr是NULL指针,则函数什么事都不用做

free也声明在stdlib.h头文件中

为了防止成为空指针,我们free之后需要把这个指针置空

3.2.2 calloc

在C语言中,还提供了一个函数叫calloc,calloc函数也用来动态内存分配,原型如下:

void* calloc (size_t num, size_t size);

同样,我们认识一下这个函数calloc - C++ Reference (cplusplus.com)

  • 函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0
  • 与malloc的区别只在于calloc会在返回地址之前把申请的空间的每个字节初始化为全0

和malloc对比:

这是malloc开辟的空间(不会初始化)

这是calloc开辟的空间(初始化为0)

如果我们对申请的内存空间的内容要求初始化,那么就可以很方便的使用calloc函数来完成任务

3.2.3 realloc

  • realloc函数的出现让动态内存管理更加灵活
  • realloc函数可以做到对动态开辟内存大小的调整

函数原型如下:

void* realloc (void* ptr, size_t size);

realloc - C++ Reference (cplusplus.com)

  • ptr是要调整的内存地址
  • size是调整之后的大小
  • 返回值为调整之后的内存起始位置
  • 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间 

realloc开辟空间也可能会失败,失败的时候返回NULL

realloc在调整内存空间的时候存在两种情况:

  • 情况1:原有空间之后有足够大的空间
  • 情况2:原有空间之后没有足够大的空间

3.3 常见的动态内存错误

3.3.1 对NULL指针的解引用操作

不做返回值判断,就可能使用NULL指针

所以我们在使用的时候,一定要判断返回值

if (p == NULL)

动态开辟的内存也是有范围的

3.3.2 对非动态开辟内存使用free释放

3.3.3 使用free释放一块动态开辟内存的一部分

void test()
{
	int* p = (int*)malloc(100);
	p++;
	free(p);
	//p不再指向动态内存的起始位置
}

3.3.4 对同一块动态内存多次释放 

3.3.5 动态开辟内存忘记释放(内存泄漏) 

4.C语言文件操作

4.1 为什么使用文件

程序运行起来的时候,程序中的数据都是放在内存中

如果要保存这些数据,不至于丢失,我们可以使用文件保存信息

使用文件我们可以将数据直接存放到电脑的硬盘上,做到了数据的持久化

4.2 什么是文件

磁盘上的文件是文件

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

4.2.1 程序文件

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

4.2.2 数据文件

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

接下来我们讨论数据文件

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

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

4.2.3 文件名 

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

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

例如: c:\code\test.txt

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

4.3 文件的打开和关闭

4.3.1 文件指针

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

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)

这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名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;

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异

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

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

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

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

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

也就是说,通过文件指针变量能够找到与它关联的文件

 

4.3.2 文件的打开和关闭 

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

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

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

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

打开方式如下: 

4.3.3 fopen函数

我们学习一下fopen函数fopen - C++ Reference (cplusplus.com)

我们总结出来了一些文件的打开方式:

打开文件的基本操作:

如果没有该文件,则返回一个NULL指针,返回一个错误

4.3.4 fclose函数

我们学习一下fclose函数fclose - C++ Reference (cplusplus.com)

为了防止pf成为野指针,这里我们把它置为空指针

fopen和fclose函数跟动态内存开辟有相似的地方:他们都是对资源的管理和使用

运行刚刚的代码,我们发现在这个文件的地址下,就生成了data.txt 文件 

这里我们还要了解一下绝对路径和相对路径的概念

相对路径:

. 表示当前路径

.. 表示上一级路径

举例说明一下:

 ​​​​

绝对路径:

 举例说明:

4.4 文件的顺序读写

4.4.1 顺序读写函数介绍

fgetc和fputc函数

fputc - C++ Reference (cplusplus.com)

fgetc - C++ Reference (cplusplus.com)

 使用一下fputc函数:

4.4.2 输入流和输出流

其实我们在写文件的时候,打开文件、关闭文件

scanf从键盘上读取数据

printf向屏幕上打印数据

直接就操作了,这是因为:C语言程序,只要运作起来,默认就打开了三个流

  1. 标准输入流 - stdin
  2. 标准输出流 - stdout
  3. 标准错误流 - stderr

4.4.3 对比一组函数

对比scanf和printf函数

  • scanf 是格式化的输入函数,针对的是标准输入流(键盘)
  • printf 是格式化的输出函数,针对的是标准输出流(屏幕)
  • scanf和printf是针对标准输入/输出流的格式化输入/输出函数
  • fscanf 是针对所有输入流(文件流、标准输入流)的格式化输入函数
  • fprintf 是针对所有输出流(文件流、标准输出流)的格式化输出函数
  • sscanf 将字符串转换成格式化的数据
  • sprintf 将格式化的数据转换成字符串

4.5 文件的随机读写

4.5.1 fseek函数

根据文件指针的位置和偏移量来定位文件指针

fseek - C++ Reference (cplusplus.com)

4.5.2 ftell函数 

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

ftell - C++ Reference (cplusplus.com)

4.5.3 rewind函数 

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

rewind - C++ Reference (cplusplus.com)

4.6 文本文件和二进制文件

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

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

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换

以ASCII字符的形式存储的文件就是文本文件

 一个数据在内存中是怎么存储的呢?

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

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

4.7 文件读取结束的判定

4.7.1 被错误使用的feof

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

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

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

例如:

  • fgetc判断是否为EOF
  • fgets判断返回值是否为NULL

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

例如:

  • fread判断返回值是否小于实际要读的个数

ferror - 在文件读取结束后,用来判断文件是否因为读取过程中遇到错误而结束

feof - 在文件读取结束后,用来判断文件是否因为读取过程中遇到文件结束标志而结束 

4.7.2 fread函数

fread - C++ Reference (cplusplus.com)

fread要求读取count各大小为size字节的数据

如果真的读取到count个数据,函数返回count

如果没有读取到count个数据,返回的是真实的读取到的完整的数据个数 

4.8 文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上

如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)

缓冲区的大小根据C编译系统决定的

结论:

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件

如果不做,可能导致读写文件的问题

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

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

相关文章

四阶Runge-Kutta方法求解高阶微分方程

一、经典的Runge-Kutta方法&#xff08;四级四阶RK方法&#xff09; Runge-Kutta法&#xff08;简写为RK方法&#xff09;既可达到较高精度&#xff0c;又可避免高阶导数计算。 对微分方程,在区间上的四阶Runge-Kutta方法的公式如下&#xff1a; 二、利用4阶Runge-Kutta方法计…

Elasticsearch - Docker安装Elasticsearch8.12.2

前言 最近在学习 ES&#xff0c;所以需要在服务器上装一个单节点的 ES 服务器环境&#xff1a;centos 7.9 安装 下载镜像 目前最新版本是 8.12.2 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置 新增配置文件 elasticsearch.yml http.host…

.locked勒索病毒是什么,企业数据被加密了如何恢复?

.locked勒索病毒介绍 .locked勒索病毒是一种恶意软件&#xff0c;它利用加密技术锁定用户的数据或系统&#xff0c;并以此进行勒索。用户一旦感染此病毒&#xff0c;将无法访问其重要文件&#xff0c;病毒会要求用户支付一笔赎金以获取解密密钥。这种病毒通常使用强大的加密算法…

为什么选VR全景技术进行乡村展示,VR全景技术助力乡村振兴

引言&#xff1a; 在科技飞速发展的当下&#xff0c;乡村振兴成为国家重要战略&#xff0c;如何创新性地展示乡村特色&#xff0c;提升乡村吸引力&#xff0c;成为当务之急。VR全景技术&#xff0c;作为一种新兴的展示手段&#xff0c;可以为乡村展示提供全新的视角&#xff0…

可观测性体系建设后,该如何挖掘数据及工具价值?

在现代企业的运维管理中&#xff0c;构建高效且可靠的可观测性体系是保障系统稳定性和业务连续性的关键。然而&#xff0c;运维团队成员的技术能力参差不齐往往成为实现这一目标的障碍。尤其在处理复杂系统故障时&#xff0c;高度依赖专业知识和经验的可观测性工具很难被全员有…

如何在Linux Ubuntu系统安装Nginx服务并实现无公网IP远程连接

文章目录 1. 安装Docker2. 使用Docker拉取Nginx镜像3. 创建并启动Nginx容器4. 本地连接测试5. 公网远程访问本地Nginx5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 在开发人员的工作中&#xff0c;公网远程访问内网是其必备的技术需求之一。对于…

vue key的bug

今天遇到一个bug&#xff0c;列表删除元素时&#xff0c;明明在外层设置了key&#xff0c;但是列表元素的状态居然复用了&#xff0c;找了好久原因&#xff0c;最后是key的取值问题&#xff0c;记录一下。 首先key可以取undefine&#xff0c;这个是不会报错的 然后项目的代码结…

C#配置连接数据库字段

在Web.config文件中 添加如下配置 <!--连接数据库字段--><connectionStrings><add name"sql" connectionString"server.;uidsa;pwd8888;databaseArticleWebSite" /></connectionStrings>

element plus等框架中属性值是组件如何传入,替换分页图标

在 Vue 中替换element plus 分页图标 正常写法引入组件 import prevIcon from /components/xx.vue;<el-pagination layout"prev, pager, next" :prev-icon"prevIcon" :total"5" />利用 h 函数写法 const prevIcon h(div, [xr]);可以写…

发送邮件接口的工作原理?有哪些常用参数?

发送邮件接口的功能有哪些&#xff1f;如何选择发送邮件接口&#xff1f; 无论是商务沟通、信息传递还是个人交流&#xff0c;发送邮件都是一种高效且便捷的方式。而在这背后&#xff0c;发送邮件接口发挥着至关重要的作用。那么&#xff0c;发送邮件接口的工作原理究竟是怎样…

springboot网站开发如何配置log4j日志插件

springboot网站开发如何配置log4j日志插件&#xff01;为了便于服务器等环境下的错误情况的排查根源&#xff0c;还是很有必要使用日志插件的&#xff0c;它可以记录下我们提前埋下的锚点信息。 在遇到故障&#xff0c;查看这些锚点记录的日志信息&#xff0c;可以快速高效的解…

C++第九弹---类与对象(六)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 日期类 1、日期类的分析和设计 1.1、日期类的功能说明 1.2、日期类的分析和设计 1.2.1、数据结构的分析 1.2.2、文件结构设计 2、日期类的结构分析…

深度学习 精选笔记(13.1)卷积神经网络-LeNet模型

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

HCIA复习

上面的文件里有思维导图哦~ 一、情景再现&#xff1a;ISP网络为学校提供了DNS服务&#xff0c;所以&#xff0c;DNS服务器驻留在ISP网络内&#xff0c;而不再学校网络内。DHCP服务器运行在学校网络的路由器上。 小明拿了一台电脑&#xff0c;通过网线&#xff0c;接入到校园网…

使用el-cascader组件写下拉级联多选并且具有全选功能

样式 说明: 级联选择器中加上全选的按钮, 并且保证数据响应式。 思路 因为是有全选的功能,所以不能直接使用el-cascader组件, 而是选择使用el-select组件, 在此组件内部使用el-cascader-panel级联面板全选按钮也是写在el-select组件中, 并且去监听全选按钮的状态, 根…

The Open Group开放数字标准组合|管理您的数字景观

据麻省理工学院斯隆Sloan和凯捷咨询Capgemini称&#xff0c;90%的首席执行官认为数字经济将影响他们的行业&#xff0c;但只有不到15%的首席执行官正在执行数字战略。 数字化转型对于企业在当今不断变化的市场和技术环境中持续保持竞争力至关重要。近年来&#xff0c;商业世界发…

‍Java OCR技术全面解析:六大解决方案比较

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

HarmonyOS ArkTS 基础组件

目录 一、常用组件 二、文本显示&#xff08;Text/Span) 2.1 创建文本 2.2 属性 2.3 添加子组件(Span) 2.4 添加事件 三、按钮&#xff08;Button&#xff09; 3.1 创建按钮 3.2 设置按钮类型 3.3 悬浮按钮 四、文本输入&#xff08;TextInput/TextArea&#xff09;…

vue-生成二维码

安装 yarn add qrcodejs2 --save npm install qrcodejs2 --save 使用 <template><div><div id"qrcodeImg"></div><!-- 创建一个div&#xff0c;并设置id --></div> </template> <script> import QRCode from q…

vue3中如何实现多个侦听器(watch)

<body> <div id"app"><input type"button" value"更改名字" click"change"> </div> <script src"vue.js"></script> <script>new Vue({el: #app,data: {food: {id: 1,name: 冰激…