【C语言】—— 文件操作(下)

news2024/12/23 18:55:51

  

前言:

  
  
  在 【C语言】—— 文件操作(上) 一文中,我们对文件有了一个简单的了解,并学会了如何打开和关闭文件,下面就让我们一起来学学如何对文件进行读写吧。
  
  

五、文件的顺序读写

5.1、 顺序读写函数介绍

函数名功能适用于
fgetc字符输入函数所有输入流
fputc字符输出函数所有输出流
fgets文本行输入函数所有输入流
fputs文本行输出函数所有输出流
fscanf格式化输入函数所有输入流
fprintf格式化输出函数所有输出流
fread二进制输入文件
fwrite二进制输出文件

  注:上面说的适用于所有输入流一般指适用于标准输入流和其他输入流(如文件输入流);所有输出流一般指适用于标准输出流和其他输出流(如文件输出流)

  下面我们对上述函数一一进行介绍
  

5.2、 f p u t c fputc fputc 函数

在这里插入图片描述

  • 函数功能将一个字符写入流中,这个流其实就是文件流
  • 函数参数
    • i n t int int c h a r a c t e r character character要写入的字符,字符的本质就是 A S C I I ASCII ASCII 码值,因此这里参数类型为 i n t int int 没有问题
    • F I L E FILE FILE * s t r e a m stream stream :指向要写入文件的文件指针
  • 返回类型:返回类型是 int:当写入成功,返回写入的值,当写入失败,返回EOF(-1)
      

函数使用:

#include<stdio.h>

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

	//写文件
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	//写入26个字母
	char ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		fputc(ch, pf);
	}

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

在这里插入图片描述

  这样,字符就写好了。
  
  当写入字符时,还有一些细节需要注意:当一个文件打开时,最开始其实是有一个光标指向第一个位置,每当用 f p u t c fputc fputc 函数写入一个字符光标则后退一格。光标是用来维护此时此刻我们这个文件写到哪的,而且是按照一定的顺序往后走的,因此叫做顺序读写

  

5.3、 f g e t c fgetc fgetc 函数

在这里插入图片描述

  • 函数功能:从流(文件)中获取一个字符
  • 返回值:返回类型为 i n t int int 。如果成功,就会将读到的字符返回,如果读取失败或者遇到文件末尾返回EOF(-1)
    • 为什么返回类型是 int 呢?正是因为它会返回两种类型的值:字符的 A S C I I ASCII ASCII码 值EOF;如果返回类型为 char,则 EOF 无法返回
        

函数使用:

#include<stdio.h>

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

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

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

运行结果:

在这里插入图片描述

  而同样,以只读的方式打开文件,刚开始光标是在第一个位置,即指向 a a a每读一个字符,光标向后退一位

  

5.4、 f p u t s fputs fputs 函数

在这里插入图片描述

  • 函数功能将 str 字符串写入文件流中,直至遇到 ‘\0’ 停止(‘\0’不会被写入)

   注:多次调用该函数,并不会实现主动换行,要想换行应主动输入‘\n’
  
函数使用:

#include<stdio.h>

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

	//写文件
	fputs("hello", pf);
	fputs("world\n", pf);
	fputs("hello csdn\n", pf);

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

	return 0;
}

运行结果:
在这里插入图片描述
  我们可以看到,加了换行符后,文件的光标是直接落到下一行的。

  

5.5、 f g e t s fgets fgets 函数

在这里插入图片描述

  • 函数功能从流中最多读取 num 个字符,并放在 str 所指向的空间中
    • 函数读 n u m num num 个字符,但是最多只能读取 n u m num num - 1个,因为最后一个位置函数会自己加上 ‘\0’
    • 该函数不会换行读取。当 n u m num num 大于字符数时,遇到换行符 ‘\n’,将 ‘\n’ 读取后,不再往下读取,自己加上 ‘\0’ 后停止。
    • 当函数读取成功,返回的是目标空间的地址;读取失败则返回空指针(NULL)

  
函数使用:

#include<stdio.h>

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

	//读文件
	char arr1[10] = "xxxxxxxxx";
	fgets(arr1, 8, pf);

	char arr2[10] = "xxxxxxxxx";
	fgets(arr2, 8, pf);


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

	return 0;
}

运行结果:

在这里插入图片描述

  

5.6、 f p r i n t f fprintf fprintf 函数

在这里插入图片描述

  
  该函数的功能是将数据以格式化的形式写入流中(以文本的形式)
  
  其实, f p r i n t f fprintf fprintf 函数 p r i n t f printf printf 函数是非常相像的,让我们来对比一下
  

在这里插入图片描述

  
  他们的区别仅仅是第一个参数的有无而已,其他都是一模一样的,所以你会用 p r i n t f printf printf你就会用 f p r i n t f fprintf fprintf
  
  多的一个参数是什么呢?是文件流,你需要将数据输出到的那个文件流
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "张三", 20, 75.5f };

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

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

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

运行结果:
在这里插入图片描述
  

5.7、 f s c a n f fscanf fscanf 函数

在这里插入图片描述

  
  该函数的功能是从文件流中读取格式化的数据。
  
  不难发现, f s a n f fsanf fsanf s c a n f scanf scanf 函数很像,我们来对比一下

  

在这里插入图片描述

  
  同 f p r i n t f fprintf fprintf 一样, f s c a n f fscanf fscanf s c a n f scanf scanf 只是相差一个参数而已,你会用 s c a n f scanf scanf 自然也就会用 f s c a n f fscanf fscanf 函数,第一个参数即是你所要读取的文件流
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { 0 };

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

	//读文件
	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
	//printf("%s %d %.2f\n", s.name, s.age, s.score);
	fprintf(stdout, "%s %d %.2f\n", s.name, s.age, s.score);
	
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

  
运行结果:

在这里插入图片描述

  注意看,上述代码用了 f p r i n t f fprintf fprintf 来将数据打印在屏幕上

  还记得最开始的表格中, f p r i n t f fprintf fprintf 最后一列写的是所有输出流吗?这所有输出流就包括了文件流标准输出流,既然 f p r i n t f fprintf fprintf 可以输出到文件中,那么自然也就可以输出到屏幕中,完成 p r i n t f printf printf 一样的功能。

  而同理,前面讲的 f p u t c fputc fputc f g e t s fgets fgets f s c a n f fscanf fscanf 等函数也可以从标准输入(输出)流中获取(输出)数据。

  

5.8、 p r i n t f / f p r i n t f / s p r i n t f printf/fprintf/sprintf printf/fprintf/sprintf 函数对比

  
通过我们前面的学习,我们已经知道了 p r i n t f printf printf f p r i n t f fprintf fprintf 函数的作用:

  • p r i n t f printf printf:把数据以格式化的形式打印在标准输出流
  • f p r i n t f fprintf fprintf : 把数据以格式化的形式打印在 指定的输出流

那么 s p r i n t f sprintf sprintf 函数又是作什么的呢?我们一起来看看

在这里插入图片描述

  
  该函数的作用是:将数据以格式化的形式写到字符串。其实就是把格式化的数据转换成字符串
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "张三", 20, 75.5f };
	char buf[50] = { 0 };
	sprintf(buf, "%s %d %f", s.name, s.age, s.score);
	printf("%s\n", buf);
	return 0;
}

运行结果:
在这里插入图片描述
  该代码完全是以 %s 的形式打印的,说明数据已经完全转换成字符串了。

  

5.9、 s c a n f / f s c a n f / s s c a n f scanf/fscanf/sscanf scanf/fscanf/sscanf 函数对比

  同样,通过我们前面的学习,我们已经知道了 s c a n f scanf scanf f s c a n f fscanf fscanf 函数的作用:

  • s c a n f scanf scanf:从 标准输入流 中读取格式化的数据
  • f s c a n f fscanf fscanf:从 指定输入流 中读取格式化的数据

  那 s s c a n f sscanf sscanf 的功能又是什么呢?学习了 s p r i n t f sprintf sprintf ,我们猜测,其应该是从字符串中读取格式化数据,是不是呢?我们一起来看看
  

在这里插入图片描述

  
函数功能从字符串中读取格式化数据
  

#include<stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "张三", 20, 75.5f };
	char buf[50] = { 0 };
	sprintf(buf, "%s %d %f", s.name, s.age, s.score);
	
	struct S a = { 0 };
	sscanf(buf, "%s %d %f", s.name, &(s.age), &(s.score));
	printf("%s %d %f\n", s.name, s.age, s.score);
	return 0;
}

运行结果:

在这里插入图片描述

  
  

5.10、 f w r i t e fwrite fwrite 函数

在这里插入图片描述

  • 函数功能:以二进制的形式将内存块中的数据入文件中
  • 参数介绍
    • c o n s t const const v o i d void void * p t r ptr ptr p t r ptr ptr 是指向要写入数据的数组的指针
    • s i z e size size_ t t t s i z e size size:表示要写入的每个元素的大小
    • s i z e size size_ t t t c o u n t count count:表示要写入元素的个数

  
下面我们直接上代码:

#include<stdio.h>

int main()
{
	int arr[] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	FILE* pf = NULL;
	pf = fopen("test.txt", "wb");
	if (NULL == pf)
	{
		perror("fopen fail");
		return 1;
	}

	fwrite(arr, sizeof(arr[0]), sz, pf);


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

  
我们以二进制的方式打开:

在这里插入图片描述

  

5.11、 f r e a d fread fread 函数

在这里插入图片描述

  该函数的作用是:以二进制的形式读取数据到内存中

  我们可以看到,这函数的参数与 f w r i t e fwrite fwrite 是大同小异的,这里就不一一介绍了,我们直接上代码

#include<stdio.H>

int main()
{
	int arr[5] = { 0 };

	FILE* pf = NULL;
	pf = fopen("test.txt", "rb");
	if (NULL == pf)
	{
		perror("fopen fail");
		return 1;
	}

	fread(arr, sizeof(arr[0]), 5, pf);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

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

运行结果:

在这里插入图片描述

  但是,上面代码是我提前知道了总共的数据个数,当我不知道数据具体个数是又该怎么办呢?

  这里,我们需要知道 f r e a d fread fread 函数的返回值,该函数的返回值是读取到的数据的个数。这时,当我要求读 7 个数据,而返回值是 5 时,说明数据读完了。

  上面的代码我们可以做如下修改:

#include<stdio.h>

int main()
{
	int arr[5] = { 0 };

	FILE* pf = NULL;
	pf = fopen("test.txt", "rb");
	if (NULL == pf)
	{
		perror("fopen fail");
		return 1;
	}

	int i = 0;
	while (fread(arr + i, sizeof(arr[0]), 1, pf))
	{
		printf("%d ", arr[i]);
		i++;
	}
	printf("\n");

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

  
  

六、文件的随机读写

  前面我们所学习到的函数都是顺序读写,光标是依次往后移动。那能不能做到随机读写呢,即我想在哪里读写就在哪读写,指那打那。

  当然是可以的,下面让我们一起来学习。
  

6.1、 f s e e k fseek fseek 函数

在这里插入图片描述

  • 功能:根据文件指针的位置和偏移量来定位文件指针(光标)
  • 参数介绍
    • l o n g long long i n t int int o f f s e t offset offset:相对于起始位置的偏移量,可正可负
    • i n t int int o r i g i n origin origin起始位置

起始位置选择:

常量所指位置
SEEK_SET文件的起始位置
SEEK_CUR当前光标位置
SEEK_END文件结尾

  
  这个函数有什么用呢?比如文件中有 a b c d e f g abcdefg abcdefg 的数据,当前光标指向 a a a,而我想直接读 e e e,这时就可以用该函数移动光标啦。
  

在这里插入图片描述

例子:

#inclu<stdio.h>

int main()
{
	FILE* pf = NULL;
	pf = fopen("test.txt", "r");
	if (NULL == pf)
	{
		perror("fopen fail");
		return 1;
	}

	char ch = 0;
	ch = fgetc(pf);
	printf("%c\n", ch);

	fseek(pf, 3, SEEK_CUR);
	ch = fgetc(pf);
	printf("%c\n", ch);

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

运行结果:

在这里插入图片描述

  
  

6.2、 f t e l l ftell ftell 函数

在这里插入图片描述

f t e l l ftell ftell 函数会返回文件指针(光标) 相对于文件起始位置的 偏移量

  这里,我们想:如果我们让光标读到文件末尾,在返回偏移量,是不是就能知道文件的长度呢?答案是肯定的。
  
例子:

#includ<stdio.h>

int main()
{
	FILE* pf;
	long size;
	pf = fopen("test.txt", "rb");
	if (NULL == pf)
		perror("Error opening file");
	
	fseek(pf, 0, SEEK_END); // non-portable
	size = ftell(pf);
	fclose(pf);
	printf("Size of test.txt: %ld bytes.\n", size);
	
	return 0;
}

  
  

6.3、 r e w i n d rewind rewind 函数

在这里插入图片描述

   r e w i n d rewind rewind 函数可以让文件指针回到起始位置

  走的太远,别忘了回头路

例子:

#include<stdio.h>

int main()
{
	int n;
	FILE* pf;
	char buffer[27];
	pf = fopen("test.txt", "w+");
	for (n = 'A'; n <= 'Z'; n++)
	{
		fputc(n, pf);
	}
	rewind(pf);
	fread(buffer, 1, 26, pf);
	fclose(pf);
	buffer[26] = '\0';
	printf(buffer);
	return 0;
}

  
  

七、文件读取结束的判定

7.1、 被错误使用的 f e o f feof feof

  
  很多人都以为 f e o f feof feof函数是用来直接判断文件读取是否结束。其实这是大错特错的
   f e o f feof feof 的作用是:当文件读取结束时,判断读取结束的原因是否是因为:遇到文件末尾结束

  现在假设文件读取结束了,但是是什么原因读取结束的呢?

  1. 有可能遇到文件末尾
  2. 读取的时候发生了错误

   f e o f feof feof 函数是判断是否是因为遇到文件末尾而结束的。
  而还有个函数叫 f e r r o r ferror ferror 是用来判断是否是因为遇到错误而读取结束的
  

  其实在我们打开一个流时,会有两个标记值

  1. 是否遇到文件末尾
  2. 是否发生错误
      

  当读文件的过程中确实是遇到文件末尾了,就会将第一个值标记;遇到错误就会将第二个值标记
   f e o f feof feof是用来检测第一个标记的; f e r r o r ferror ferror是用来检测第二个标记

f e o f feof feof 函数:当文件确实是因为读取到文件末尾而结束时,返回一个非零值,反之返回 0
  
  

7.2、如何判断文件读取结束

  那么如何来判断文件是否读取结束呢?其实在前面结束各个函数时已经顺便介绍了:通过函数的返回值进行判断!
  

(1)文本文件判断

函数名正常读取返回值读取结束或遇到错误的返回值
fgetc返回读取到的字符的ASCII码值EOF
fgets返回目标空间的地址NULL

  

(2)二进制文件判断

  二进制文件用 f r e a d fread fread 进行读取, f r e a d fread fread 返回值是其读取到的个数。当其返回值小于实际要读取的个数时,表示文件读取结束

  

八、 文件缓冲区

  我们想一个问题:当我们想往文件中存 26 个字母,这 26 个字母是直接从程序(内存)中存到文件(硬盘)中的吗?
  其实不是的。

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

  从内存向磁盘输出数据会先送达内存中的缓冲区装满缓冲区主动刷新缓冲区才将数据送到磁盘上。

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

  缓冲区的大小根据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语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件

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


  好啦,本期关于文件操作的知识就介绍到这里啦,希望本期博客能对你有所帮助。同时,如果有错误的地方请多多指正,让我们在C语言的学习路上一起进步!

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

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

相关文章

VUE Pinia状态持久化

效果 实现方法 插件&#xff1a;pinia-plugin-persistedstate 链接地址 具体操作 安装 npm i pinia-plugin-persistedstate 添加到 pinia 实例上 import { createPinia } from pinia import piniaPluginPersistedstate from pinia-plugin-persistedstateconst pinia cre…

申请SSL证书 SSL是如何保护网站安全的

随着互联网的不断发展&#xff0c;网络安全问题日益凸显&#xff0c;特别是在数据传输和存储方面。为了保护网站和用户的数据安全&#xff0c;SSL&#xff08;安全套接层&#xff09;技术应运而生&#xff0c;成为了保护网站安全的重要工具。本文将详细介绍SSL如何保护网站安全…

【问题解决】plt.show()画出来的图像只在pycharm右侧栏显示

问题情况如下&#xff1a; 画出的图只在右侧栏显示&#xff0c;而我们想弹出一个独立的窗口&#xff0c;拖动鼠标可以360度查看图像&#xff0c;还可以保存图片。 【 问题解决 】&#xff1a; File -> Settings ->Tools-> Python Scientific -> 将“Show plots i…

Python从0到100(三十六):字符和字符集基础知识及其在Python中的应用

1. 字符和字符集概述 字符(Character)是构成书面语言的基本元素&#xff0c;它包括但不限于各国家的文字、标点符号、图形符号和数字。字符集(Character set)则是一个包含多个字符的系统&#xff0c;用于统一管理和编码不同的字符。 常见字符集 ASCII&#xff1a;最早的字符…

初尝PaddleOCR识别图片中的文字

引言 PaddleOCR是一个基于飞桨深度学习框架的OCR工具包&#xff0c;它集成了丰富的文字检测、识别和后处理算法&#xff0c;能够高效、准确地识别出图片中的文字。 说明 OpenVINO.NET是一个由开源开发者sdcb发布的&#xff0c;一个个强大的工具集&#xff0c;通过优化神经网…

高性价比模块:LSYT201B语音模块学习使用

最近打算做个语音的项目&#xff0c;找到了深圳雷龙发展的LSY201B这款语音模块&#xff0c;写出来安利一下 程序源码&#xff1a;SuiXinSc/Speech-Module (github.com) 或者进入Q群找我获取 目录 一&#xff0c;简要介绍&#xff1a; 硬件参数&#xff1a; 1&#xff0c;处理…

Spring MVC 中使用 RESTFul 编程风格

1. Spring MVC 中使用 RESTFul 编程风格 文章目录 1. Spring MVC 中使用 RESTFul 编程风格2. RESTFul 编程风格2.1 RESTFul 是什么2.2 RESTFul风格与传统方式对比 3. Spring MVC 中使用 RESTFul 编程风格(增删改查)的使用3.1 准备工作3.2 RESTFul 风格的 “查询” 所有&#xf…

Linux-页表如何对物理内存进行映射

1.1 页框和页帧 我们知道通过页表可以将虚拟内存映射到对应的物理内存&#xff0c;而操作系统对于物理内存的管理并不是以字节为单位的&#xff0c;而是将物理内存分为许多大小为4KB的块&#xff0c;称为页框或页帧&#xff0c;这就是为什么我们在创建共享内存是建议将大小设定…

2024年7月4日 (周四) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 卸载工具 HiBitUninstaller: Windows上的软件卸载工具 《最终幻想14》画面升级后 著名…

YOLOv10全网最新创新点改进系列:融合GSConv+Slim Neck,双改进、双增强,替换特征融合层实现, 轻量化涨点改进策略,有效涨点神器!

YOLOv10全网最新创新点改进系列&#xff1a;融合GSConvSlim Neck&#xff0c;双改进、双增强&#xff0c;替换特征融合层实现&#xff0c; 轻量化涨点改进策略&#xff0c;有效涨点神器&#xff01; 所有改进代码均经过实验测试跑通&#xff01;截止发稿时YOLOv10已改进40&…

【刷题笔记(编程题)05】另类加法、走方格的方案数、井字棋、密码强度等级

1. 另类加法 给定两个int A和B。编写一个函数返回AB的值&#xff0c;但不得使用或其他算数运算符。 测试样例&#xff1a; 1,2 返回&#xff1a;3 示例 1 输入 输出 思路1: 二进制0101和1101的相加 0 1 0 1 1 1 0 1 其实就是 不带进位的结果1000 和进位产生的1010相加 无进位加…

H5实现第三方分享功能,(WhatsApp,Facebook,Messenger,Instagram,Telegram,Zalo,Twitter/X)

1. H5实现第三方分享功能 1. WhatsApp 分享 https://api.whatsapp.com/send/?phone&app_absent0&text${codeUrl}2. Facebook 分享 https://www.facebook.com/sharer/sharer.php?u${codeUrl}3. Messenger 分享 https://www.messenger.com/?${codeUrl}4. Instagra…

​​服务拆分的原则

目录 一、单一职责原则 二、服务自治原则 三、单向依赖 一、单一职责原则 单⼀职责原则原本是面向对象设计中的⼀个基本原则, 它指的是⼀个类应该专注于单⼀功能. 不要存在多于⼀个导致类变更的原因 在微服务架构中, ⼀个微服务也应该只负责⼀个功能或业务领域, 每个服务应该…

代码随想录算法训练营第70天图论9[1]

代码随想录算法训练营第70天:图论9 ‍ 拓扑排序精讲 卡码网&#xff1a;117. 软件构建(opens new window) 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的…

html+css+js淘宝商品界面

点击商品&#xff0c;alert弹出商品ID 图片使用了占位符图片&#xff0c;加载可能会慢一点 你可以把它换成自己的图片&#x1f603;源代码在图片后面 效果图 源代码 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"…

嵌入式底层系统了解

当裸机功能不复杂的时候&#xff0c;即类似与点亮一个LED灯&#xff0c;驱动LCD和OLED这样的模块&#xff0c;以及各位大学生的搭积木式的毕业设计(狗头保命&#xff09;&#xff0c;此时可以简单地分为硬件和软件层&#xff08;应用层),以及以中间层作为中间联系。 当需要实现…

代码随想录算法训练营第2天|LeetCode977,209,59

977.有序数组平方 题目链接&#xff1a; 977. 有序数组的平方 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a; 双指针法经典题目 | LeetCode&#xff1a;977.有序数组的平方_哔哩哔哩_bilibili 第一想法 暴力算法肯定是先将元素…

docker的安装与基本使用

一.docker的安装卸载 1.先安装所需软件包 yum install -y yum-utils2.设置stable镜像仓库 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 3.安装DOCKER CE yum -y install docker-ce docker-ce-cli containerd.io 4.验…

【unity实战】使用Unity实现动作游戏的攻击 连击 轻重攻击和打击感

最终效果 文章目录 最终效果前言素材下载&#xff1a;玩家移动跳跃控制攻击动画配置轻攻击重攻击 攻击时禁止移动和攻击移动补偿敌人击退和播放受击动画受击特效攻击停顿和屏幕震动局部顿帧&#xff08;补充&#xff09;参考源码完结 前言 注意本文为自己的学习记录笔记&#…