数据在内存的存储

数据类型介绍

前面我们已经学习了基本的内置类型:

char        //字符数据类型   1字节  打印%c           
short       //短整型       2字节    打印%hd
int         //整形      4字节   打印%d
long     =long int   //长整型        4/8字节        打印%ld
long long  =long long int //更长的整形    8字节    打印%lld
float       //单精度浮点数                4字节        打印%f
double      //双精度浮点数                8字节     打印%lf
sizeof(long)>=sizeof(int)

整形打印无符号数将格式中的d换成u就行

 类型的基本归类

整形家族:
char
unsigned char
signed char
f63cdb63e76a43d39906b89d5d62a446.png
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]
long long
浮点数家族:
float
double
long double
构造类型:
> 数组类型
45487158c3b44ff7a7c79d95776e608a.png
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union
指针类型
int *pi;
char *pc;
float* pf;
void* pv;
结构体指针等等

ad35a26ffc9345c2b50567bdfb371e4f.png

整形在内存中的存储

我们之前讲过一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同的类型而决定的。那接下来我们谈谈数据在所开辟内存中到底是如何存储的?
比如:
int a = 20;
int b = -10;
我们知道为 a 分配四个字节的空间。
那如何存储?
下来了解下面的概念:
原码、反码、补码
计算机中的整数有三种2进制表示方法,即原码、反码和补码。
三种表示方法均有 符号位数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位
正数的原、反、补码都相同。 负整数的三种表示方法各不相同。
原码
直接将数值按照正负数的形式翻译成二进制就可以得到原码。
反码
将原码的符号位不变,其他位依次按位取反就可以得到反码。

补码
反码+1就得到补码。
对于整形来说:数据存放内存中其实存放的是补码。为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统
一处理;同时,加法和减法也可以统一处理( CPU 只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

下边我们看一个数据存储的例子就好理解了

67858f98a9b8438eb9869d248b0bcf57.png

b55a4fd3101e466b8f30c0372dadd4f4.png

可以看到,数据在内存是补码存储的,并且是倒着存储的,本质上内存中存放的是2进制,为了方便显示,我们看到的都是16进制的数字(不要害怕不同进制的数字,本质上进制只是表示数字的一种形式)为什么是这样存储的呢接下来我带大家看一下

讲大小端之前我先说明一下原码反码补码的关系(整数原码,反码,补码相同,负数如下)
ee0bbfeeea314d2b85dafe630adc5b50.png
原码-》补码,先除了符号位按位取反,再+1
补码-》原码,先-1,再除了符号位按位取反
大小端介绍
什么大端小端:
大端(存储)模式,是指数据的低位字节保存在内存的高地址中,而数据的高位字节,保存在内存的低地址中;
小端(存储)模式,是指数据的低位字节保存在内存的低地址中,而数据的高位字节,,保存在内存的高地址中。
我们测试一下这个数据
081ce3fcc05445658f54b73ef3083de8.png
fda0699bcd4049bab4645610a8d3aa3e.png
我们知道数据在内存是从低地址向高地址存储的
一个数据的低位字节如果存放在内存的低地址处,代表是小端存储,反之是大端存储
有一道笔试题
百度2015年系统工程师笔试题:
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。(10分)
//小端返回1
//大端返回0
int check_sys()
{int a = 1;return *(char*)&a;
}int main()
{int ret = check_sys();if(ret == 1)cout<<"小端"<<endl;elsecout << "大端" << endl;return 0;
}

思路是什么呢

c7096f7b54524d3e8c8af253831a37c6.png

我们用char* 强转a的地址,解引用一个字节,如果拿到的是1,代表是小端存储,图上清晰明了很简单

做题之前我们介绍一个东西( 大致意思就是数据类型是有存储范围的,我们介绍char的存储范围,其他类型可以照这个类比,是很简单的)(char类型一个字节,有符号char 第一位是符号位,不参与计算,1代表负数,0代表正数,数据范围是-128~127;无符号char第一位是数值位,也参与计算,全部为正数)(所以相同类型无符号数值上限要比有符号数值高一倍)
22cfc74c112e4d15a5b55a79899b0a42.png
整形家族有这么多类型,我们怎么判断数据在内存的存储呢(注意,数据在内存中一定是以补码存储的,我们计算数据也是计算补码)
在vs上我们认为没有unsigned就是有符号类型,有unsigned就是无符号类型,有符号类型第一位存储符号位(正数是0,负数是1),无符号类型每一位都是数值位,一个字节等于8比特位,具体的计算过程上图很明显了(注意:有符号类型第一位符号位不参与计算,只算数值位,所以相对无符号类型的最大值会小一半)
adec8cbfc6a04ec1a2a939654bd699b6.png
有符号数最高位是1整型提升高位补充符号位1,最高位是0整型提升高位补充符号位0
无符号数整型提升高位补0
1.
//输出什么?
#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);//-1 -1 255
return 0;
}
先算出补码,后截断,再根据类型整型提升,最后打印(以有符号打印需要看最高位,是1说明是负数,需要转化为原码,是0直接打印,以无符号打印直接补码就是原码,所有位都是数值位并且计算)

#include <stdio.h>
int main()
{char a = -1;//10000000000000000000000000000001//11111111111111111111111111111110//11111111111111111111111111111111-截断//11111111 -a//11111111111111111111111111111111//11111111111111111111111111111110//10000000000000000000000000000001--> -1signed char b = -1;//11111111111111111111111111111111//11111111 -bunsigned char c = -1;//11111111 -c//00000000000000000000000011111111//printf("a=%d,b=%d,c=%d", a, b, c);//%d - 十进制的形式打印有符号整型整数//整型提升return 0;
}
2.
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);//%u是以十进制形式打印无符号整数
return 0;
}
//#include <stdio.h>
//int main()
//{
//	char a = -128;
//	//-128
//	//10000000000000000000000010000000//原码
//	//11111111111111111111111101111111//反码
//	//11111111111111111111111110000000//补码
//	//-128的补码
//	//10000000//截断
//	//11111111111111111111111110000000//有符号最高位补1,进行整型提升
//	//
//	printf("%u\n", a);
//	return 0;
//}

976c56b96cfe47ccac29517f747fa8d1.png打印42亿多

3.
#include <stdio.h>
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
}//这道题跟上边的题结果一样因为截断处都是1000 0000,都是有符号数,以无符号形式打印,所以结果都一样
4.
int i= -20;
unsigned  int  j = 10;
printf("%d\n", i+j);
//按照补码的形式进行运算,最后格式化成为有符号整数
//int main()
//{
//	int i = -20;
//	//10000000000000000000000000010100
//	//11111111111111111111111111101011
//	//11111111111111111111111111101100//-20的补码
//	//
//	unsigned int j = 10;
//	//00000000000000000000000000001010//10的补码
//	//11111111111111111111111111101100
//	//11111111111111111111111111110110//相加和是补码,要以有符号形式打印,符号位是1是负数,补码要转化为原码进行打印
//	//11111111111111111111111111110101
//	//10000000000000000000000000001010 -10//转化为原码//	printf("%d\n", i + j);//-10
//	return 0;
//}
//
5.
unsigned int i;
for(i = 9; i >= 0; i--)
{
printf("%u\n",i);
}
0da2a6abef4a4ddaa3b5f85f86c7ebcd.png
因为i是无符号整形,数据范围是0到42亿多,所以0--之后会是42亿多(-1的补码是32位全1,所以是42亿多)
6.
int main()
{   
char a[1000];
int i;   
for(i=0; i<1000; i++)
{       
a[i] = -1-i;
}
printf("%d",strlen(a));  
return 0;
}
e54b000991c64cb68712de27b6ea6178.png
char是有符号char,最多表示-128到127,所以数组里边只会存连续相同的,-1到-128,再从127到0,这是一轮循环,strlen函数是判断长度,到\0结束,因为\0的ascll码值是0,所以strlen到第一轮0就会结束,0之前是255个字符,所以打印255
7.
#include <stdio.h>
unsigned char i = 0;
int main()
{for(i = 0;i<=255;i++){printf("hello world\n");}return 0;
}

这个就很简单了,无符号char范围是0~255,只要进入循环i永远小于255,所以死循环

浮点型在内存中的存储

常见的浮点数:
3.14159
1E10
浮点数家族包括: float、double、long double 类型。
浮点数表示的范围:float.h中定义
8c94053589c44e2d9f67158f5a443245.png
浮点数存储的例子:
#include<iostream>
using namespace std;
#include <stdio.h>int main()
{int n = 9;////0 00000000 00000000000000000001001//S  E        M//0  -126     0.00000000000000000001001//(-1)^0 * 0.00000000000000000001001 * 2^-126////E在内存中是全0//float* pFloat = (float*)&n;printf("n的值为:%d\n", n);//9printf("*pFloat的值为:%f\n", *pFloat);//0.000000*pFloat = 9.0;//1001.0//1.001 * 2^3//(-1)^0 * 1.001 * 2^3//S=0     E=3  M=1.001//0 10000010 00100000000000000000000//printf("num的值为:%d\n", n);//1091567616printf("*pFloat的值为:%f\n", *pFloat);//9.0return 0;
}

先把这个代码放在这,现在先描述一下浮点数如何在内存存储,再返回来看这道题

72ed468c19104450bfcae7bc13db1278.png

对于64位的浮点数,最高的1位是符号位,接着的11位是指数E,剩下的52位为有效数字M。

d66c860bd00f46819a9dd7d3c715af9e.png

第一个是float,第二个是double

下边有点长,我把关键部分加粗了,理解起来轻松些

浮点数存储规则
num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?
要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。
详细解读:根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
举例来说:
十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2
那么,按照上面V的格式,可以得出S=0,M=1.01,E=2。
IEEE 754 对有效数字 M 和指数 E ,还有一些特别规定。
前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。
IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。 (提高数字的精度,意思就是说M只存小数位,不够补0)
至于指数 E ,情况就比较复杂。
首先, E 为一个无符号整数( unsigned int
这意味着, 如果 E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047 但是,我们知道,科学计数法中的E是可以出现负数的, 所以IEEE 754 规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间
数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即
10001001。然后,指数E从内存中取出还可以再分成三种情况:
E 不全为 0 或不全为 1(绝大多数情况,意思就是说怎么放进去怎么拿出来),(放进去+127/1023,拿出来-127/1023)
这时,浮点数就采用下面的规则表示, 即指数 E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
比如: 0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为 1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:00111111000000000000000000000000
E全为0(说明放进去之前是0-127/1023,表示为2^-127/2^-1023,是一个很小的值,可以忽略不计了)(这种情况了解一下就行)
这时, 浮点数的指数 E等于1-127(或者1-1023 )即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0 ,以近于0的很小的数字。
E 全为 1(说明放进去之前是127/,反正是一个很大的值,也不做重点讨论,了解)
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);
好了,关于浮点数的表示规则,就说到这里。
上边大概就是讲,我们在存储一个浮点数时,要将10进制先转化为2进制,根据国际委员会的标准算出SEM具体值,然后进行按规则存储。
有了上边的基础,下边这道题就很好理解了
#include <stdio.h>
int main()
{float f = 5.5;//101.1是2进制的5.5//1.011 * 2^2,将2进制类比位10进制进行表示很简单//(-1)^0 *1.011 * 2^2//将对应的数值填入表达式中//S = 0//M = 1.011//E = 2//0100 0000 1011 0000 0000000000000000//0x40b00000return 0;
}

对照上边的浮点数存储模型,5.5是单精度浮点数,对照单精度存储结构,S=0,M=1.011,E=2

S第一个位置就填0,E为2放进去要加127是129,二进制是10000001 ,小数点后边有三位是011,M有23比特位,011后边全补0二进制序列就没毛病了,上边我写的也有

换算成16进制是0x40b00000

d2a18eb25d6e45a399b0aea6deed1bbf.png

可以很清晰的看到内存中是小端存储,我们算的是对的,只要按照这个算法99%的浮点数我们都会算。

理解完了这道题,我们还要再看一下刚才那道题

注意,我们以整形存进去并且以整形往出拿,和以浮点型存进去并且以浮点型往出拿的结果都很单纯,以整形存进去但以浮点数往出拿和以浮点数存进去以整形往出拿的结果大大不同。

#include<iostream>
using namespace std;
#include <stdio.h>int main()
{int n = 9;////0 00000000 00000000000000000001001//S  E        M//0  -126     0.00000000000000000001001//(-1)^0 * 0.00000000000000000001001 * 2^-126////E在内存中是全0//float* pFloat = (float*)&n;printf("n的值为:%d\n", n);//9printf("*pFloat的值为:%f\n", *pFloat);//0.000000*pFloat = 9.0;//1001.0//1.001 * 2^3//(-1)^0 * 1.001 * 2^3//S=0     E=3  M=1.001//0 10000010 00100000000000000000000//printf("num的值为:%d\n", n);//1091567616printf("*pFloat的值为:%f\n", *pFloat);//9.0return 0;
}

整数n在内存中正常存储,原码反码补码相同,注意,我们计算的永远是内存中的补码,打印打的是内存中的原码,当把整数int类型以浮点数形式往出拿的时候,根据国际标准IEEE(电气和电子工程协会) 754标准,将内存以SME表示出来,S是0,E是全0,我们刚才说过E是全0,说明我们拿出来是E是-126,M就是0.00000000000000000001001。可以看到,只要根据公式计算,就很简单。(结果是(-1)^0 * 0.00000000000000000001001 * 2^-126  打印结果是0.00000000,一个很小的数,符合我们的预期)

当我们以浮点数的形式存进去,以整数形式拿出来,9.0二进制表示为1001.0,科学计数法是1.001*2^3,根据IEEE协会标准算出来S E M分别是0,3,1.001,再以刚才的规则将其填进内存,最后以有符号形式打印,符号位是0,是正数,以有符号整数打印,正数的原码反码补码相同,将其以原码形式打印出来就是10亿这个数字。很简单吧

以上就是我对数据类型以及数据存储的介绍,感谢支持!!!以后会创作更多的文章

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot 默认的 mysql 驱动版本

本案例以 springboot 3.1.12 版本为例 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.12</version><relativePath/> </parent> 点击 spring-…

直流无刷电机控制(FOC):电流模式

目录 概述 1 系统框架结构 1.1 硬件模块介绍 1.2 硬件实物图 1.3 引脚接口定义 2 代码实现 2.1 软件架构 2.2 电流检测函数 3 电流环功能实现 3.1 代码实现 3.2 测试代码实现 4 测试 概述 本文主要介绍基于DengFOC的库函数&#xff0c;实现直流无刷电机控制&#x…

在 Flownex 网络中创建传热元件

本文探讨了在 Flownex 仿真中集成新传热元件的步骤&#xff0c;以增强热系统管理能力。 了解 Flownex 中的传热元件 Flownex 中的传热元件复制传导、对流和辐射&#xff0c;从而深入了解系统的热流体行为。准确建模复杂系统需要了解这些单元的特性和功能。Flownex 的高级功能…

《OpenCV计算机视觉实战项目》——银行卡号识别

文章目录 项目任务及要求项目实现思路项目实现及代码导入模块设置参数对模版图像中数字的定位处理银行卡的图像处理读取输入图像&#xff0c;预处理找到数字边框使用模版匹配&#xff0c;计算匹配得分 画出并打印结果 项目任务及要求 任务书&#xff1a; 要为某家银行设计一套…

PyCharm文档管理

背景&#xff1a;使用PyCharmgit做文档管理 需求&#xff1a;需要PyCharm自动识别docx/xslx/vsdx等文件类型&#xff0c;并在PyCharm内点击文档时唤起系统内关联应用(如word、excel、visio) 设置步骤&#xff1a; 1、file -》 settings -》file types 2、在Files opened i…

景联文科技提供高质量多模态数据处理服务,驱动AI新时代

在当今快速发展的AI时代&#xff0c;多模态数据标注成为推动人工智能技术进步的关键环节。景联文科技作为行业领先的AI数据服务提供商&#xff0c;专注于为客户提供高质量、高精度的多模态数据标注服务&#xff0c;涵盖图像、语音、文本、视频及3D点云等多种类型的数据。通过专…

django基于Python的智能停车管理系统

1.系统概述 1.定义&#xff1a;Django 基于 Python 的智能停车管理系统是一个利用 Django 框架构建的软件系统&#xff0c;用于高效地管理停车场的各种事务&#xff0c;包括车辆进出记录、车位预订、收费管理等诸多功能。 2.目的&#xff1a;它的主要目的是提高停车场的运营效…

【Rust】切片类型

目录 思维导图 1. 切片类型概述 2. 函数示例&#xff1a;获取字符串中的第一个单词 2.1 问题描述 2.2 初步实现 2.3 代码实现 3. 切片的引入 3.1 切片的定义 3.2 切片的优势 3.3 改进后的函数 4. 函数参数的通用性 4.1 改进函数签名 4.2 示例代码 5. 其他切片类型…

微信小程序-Docker+Nginx环境配置业务域名验证文件

在实际开发或运维工作中&#xff0c;我们时常需要在 Nginx 部署的服务器上提供一个特定的静态文件&#xff0c;用于域名验证或第三方平台验证。若此时使用 Docker 容器部署了 Nginx&#xff0c;就需要将该验证文件正确地映射&#xff08;挂载&#xff09;到容器中&#xff0c;并…

鸿蒙UI(ArkUI-方舟UI框架)

参考&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-layout-development-overview-V13 ArkUI简介 ArkUI&#xff08;方舟UI框架&#xff09;为应用的UI开发提供了完整的基础设施&#xff0c;包括简洁的UI语法、丰富的UI功能&#xff…

图片和短信验证码(头条项目-06)

1 图形验证码接口设计 将后端⽣成的图⽚验证码存储在redis数据库2号库。 结构&#xff1a; {img_uuid:0594} 1.1 创建验证码⼦应⽤ $ cd apps $ python ../../manage.py startapp verifications # 注册新应⽤ INSTALLED_APPS [django.contrib.admin,django.contrib.auth,…

SpringCloud系列教程:微服务的未来(十二)OpenFeign连接池、最佳实践、日志、微服务拆分

本篇博客将讨论如何优化 OpenFeign 的连接池配置&#xff0c;如何使用最佳实践提升服务间通信的效率和可维护性&#xff0c;并探讨如何通过拆分服务来提升微服务架构的灵活性和可扩展性&#xff0c;具体涵盖了用户服务和交易服务的拆分。 目录 前言 OpenFeign 连接池 最佳实…

进阶——十六届蓝桥杯嵌入式熟练度练习(LED的全开,全闭,点亮指定灯,交替闪烁,PWM控制LED呼吸灯)

点亮灯的函数 void led_show(unsigned char upled) { HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC,upled<<8,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RE…

动态规划【打家劫舍】

今天和大家分享一下动态规划当中的打家劫舍题目&#xff0c;希望在大家刷题的时候提供一些思路 打家劫舍1&#xff1a; 题目链接&#xff1a; 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋…

Jaeger UI使用、采集应用API排除特定路径

Jaeger使用 注&#xff1a; Jaeger服务端版本为&#xff1a;jaegertracing/all-in-one-1.6.0 OpenTracing版本为&#xff1a;0.33.0&#xff0c;最后一个版本&#xff0c;停留在May 06, 2019。最好升级到OpenTelemetry。 Jaeger客户端版本为&#xff1a;jaeger-client-1.3.2。…

Vue-Cli

一.vue.js 1.优点 1)体积小,压缩后33K 2)更高的运行效率 3)双向数据绑定 4)生态丰富,学习成本低 2.Vue指令 指令带有前缀 v- 开头&#xff0c;以表示它们是 Vue 提供的特殊属性。 1)v-text (1)作用 &#xff1a;设置标签的文本内容 默认写法会替换全部内容&#xff0c…

【源码解析】Java NIO 包中的 ByteBuffer

文章目录 1. 前言2. ByteBuffer 概述3. 属性4. 构造器5. 方法5.1 allocate 分配 Buffer5.2 wrap 映射数组5.3 slice 获取子 ByteBuffer5.4 duplicate 复刻 ByteBuffer5.5 asReadOnlyBuffer 创建只读的 ByteBuffer5.6 get 方法获取字节5.7 put 方法往 ByteBuffer 里面加入字节5.…

HTML5实现好看的中秋节网页源码

HTML5实现好看的中秋节网页源码 前言一、设计来源1.1 网站首页界面1.2 登录注册界面1.3 节日由来界面1.4 节日习俗界面1.5 节日文化界面1.6 节日美食界面1.7 节日故事界面1.8 节日民谣界面1.9 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看…

OA项目登录

导入依赖,下面的依赖是在这次OA登录中用到的 <!--web依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.sprin…

YangQG 面试题汇总

一、交叉链表 问题&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 解题思想&#xff1a; 双指针 备注&#xff1a;不是快慢指针&#xff0c;如果两个长度相…