[C]基础13.深入理解指针(5)

news2025/7/19 12:53:56
  • 博客主页:向不悔
  • 本篇专栏:[C]
  • 您的支持,是我的创作动力。

文章目录

  • 0、总结
  • 1、sizeof和strlen的对比
    • 1.1 sizeof
    • 1.2 strlen
    • 1.3 sizeof和strlen的对比
  • 2、数组和指针笔试题解析
    • 2.1 一维数组
    • 2.2 字符数组
      • 2.2.1 代码1
      • 2.2.2 代码2
      • 2.2.3 代码3
      • 2.2.4 代码4
      • 2.2.5 代码5
      • 2.2.6 代码6
    • 2.3 二维数组
  • 3、指针运算笔试题解析
    • 3.1 题目1
    • 3.2 题目2
    • 3.3 题目3
    • 3.4 题目4
    • 3.5 题目5
    • 3.6 题目6
    • 3.7 题目7


0、总结

在这里插入图片描述

1、sizeof和strlen的对比

1.1 sizeof

sizeof计算变量所占内存内存空间大小的,单位是字节。如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。sizeof只关注占用内存空间的大小,不在乎内存中存放什么数据。如下:

#include <stdio.h>
int main()
{
	int a = 10;
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof a);
	printf("%d\n", sizeof(int));
	return 0;
}

1.2 strlen

strlen是C语言库函数,功能是求字符串长度。函数原型如下:

size_t strlen(const char* str);

统计的是从strlen函数的参数str中这个地址开始向后,\0之前字符串中字符的个数。

strlen函数会一直向后找\0字符,直到找到为止,所以可能存在越界查找。

#include <stdio.h>
int main()
{
	char arr1[3] = { 'a','b','c' };
	char arr2[] = "abc";
	printf("%d\n", strlen(arr1));  // unknown
	printf("%d\n", strlen(arr2));  // 3

	printf("%d\n", sizeof(arr1));  // 3
	printf("%d\n", sizeof(arr2));  // 4
	return 0;
}
运行:
15
3
3
4

1.3 sizeof和strlen的对比

sizeofstrlen
1、sizeof是操作符。
2、sizeof计算操作数所占内存的大小,单位是字节。
3、不关注内存中存放什么数据。
1、strlen是库函数,使用需要包含头文件string.h
2、strlen是求字符串长度的,统计的是\0之前字符的隔个数。
3、关注内存中是否有\0,如果没有\0,就会持续往后找,可能会越界。

2、数组和指针笔试题解析

2.1 一维数组

做题之前,先理解概念:

  • 1、 数组名的理解:数组名是数组首元素(第一个元素的地址)
  • 2、 但有两个例外:
    • sizeof(数组名) - 数组名表示整个数组,计算的是整个数组的大小,单位是字节。
    • &数组名 - 数组名表示整个数组,取出的是整个数组的地址。
  • 3、 除此之外,所有的数组名是数组首元素的地址。
#include <stdio.h>

int main()
{
	int a[] = { 1,2,3,4 };

	printf("01:%zd\n", sizeof(a));          
	printf("02:%zd\n", sizeof(a + 0));      
	printf("03:%zd\n", sizeof(*a));         
	printf("04:%zd\n", sizeof(a + 1));     
	printf("05:%zd\n", sizeof(a[1]));       
	printf("06:%zd\n", sizeof(&a));         
	printf("07:%zd\n", sizeof(*&a));        
	printf("08:%zd\n", sizeof(&a + 1));               
	printf("09:%zd\n", sizeof(&a[0]));      
	printf("10:%zd\n", sizeof(&a[0] + 1));  
	return 0;
}
运行(32位环境):
01:16
02:4
03:4
04:4
05:4
06:4
07:16
08:4
09:4
10:4
运行(64位环境):
01:16
02:8
03:4
04:8
05:4
06:8
07:16
08:8
09:8
10:8

解析:

解析:
//01 : 16     because:sizeof(数组名)->求数组的大小。
//02 : 4/8    because:不是单独数组名,所以a是首元素的地址,类型为int*,a+0还是首元素地址。
//03 : 4      because:*a == *(a + 0) == a[0],a是首元素的地址,*a就是首元素。
//04 : 4/8    because:a是首元素的地址,a+1跳过1个整型,a+1就是第二个元素的地址。
//05 : 4      because:a[1]就是第二个元素。
//06 : 4/8    because:&a是数组的地址,所以是4/8。再次总结,sizeof(数组名)是数组的大小,sizeof(&数组名)是数组的地址。
//07 : 16     because:*&相互抵消,所以等价于sizeof(a)。
//08 : 4/8    because:&a+1是跳过整个数组后的那个位置的地址。
//09 : 4/8    because:首元素的地址。
//10 : 4/8    because:数组第二个元素的地址。

2.2 字符数组

2.2.1 代码1

#include <stdio.h>

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("01:%zd\n", sizeof(arr));
	printf("02:%zd\n", sizeof(arr + 0));
	printf("03:%zd\n", sizeof(*arr));
	printf("04:%zd\n", sizeof(arr[1]));
	printf("05:%zd\n", sizeof(&arr));
	printf("06:%zd\n", sizeof(&arr + 1));
	printf("07:%zd\n", sizeof(&arr[0] + 1));
	return 0;
}
运行(32位):
016
024
031
041
054
064
074
运行(64位):
016
028
031
041
058
068
078

解析:

解析:
//01:6     because:数组名单独放在sizeof内部,计算的是数组的大小。  
//02:4/8   because:arr是数组名表示首元素的地址,arr+0还是首元素的地址。
//03:1     because:arr是首元素的地址,*arr就是首元素。
//04:1     because:arr[1]就是第二个元素。
//05:4/8   because:&arr是数组地址。
//06:4/8   because:跳过整个数组,指向了数组后边的空间。
//07:4/8   because:第二个元素的地址。

2.2.2 代码2

#include <stdio.h>

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("01:%zd\n", strlen(arr));
	printf("02:%zd\n", strlen(arr + 0));
	//printf("03:%zd\n", strlen(*arr));
	//printf("04:%zd\n", strlen(arr[1]));
	printf("05:%zd\n", strlen(&arr));
	printf("06:%zd\n", strlen(&arr + 1));
	printf("07:%zd\n", strlen(&arr[0] + 1));
	return 0;
}
运行:
0142
0242
0542
0636
0741

解析:

解析:
//01:unknown because:arr   是首元素的地址,数组中没有\0,结果随机。
//02:unknown because:arr+0 是首元素的地址,数组中没有\0,结果随机。
//03:err     because:arr是首元素的地址,*arr是首元素,就是'a','a'的ascii码值是97
// 相当于把97作为地址传递给了strlen,strlen得到的就是野指针,代码有问题。
//04:err     because:arr[1]->'b'->98,传递给strlen也是错误的。
//05:unknown because:&arr是数组的地址,起始位置是数组的第一个元素的位置,结果随机。
//06:unknown because:随机值 x-6
//07:unknown because:随机值 x-1

2.2.3 代码3

#include <stdio.h>

int main()
{
	char arr[] = "abcdef";
	printf("01:%zd\n", sizeof(arr));
	printf("02:%zd\n", sizeof(arr + 0));
	printf("03:%zd\n", sizeof(*arr));
	printf("04:%zd\n", sizeof(arr[1]));
	printf("05:%zd\n", sizeof(&arr));
	printf("06:%zd\n", sizeof(&arr + 1));
	printf("07:%zd\n", sizeof(&arr[0] + 1));
	return 0;
}
运行(32位):
017
024
031
041
054
064
074
运行(64位):
017
028
031
041
058
068
078

解析:

解析:
//01:7     because:数组总大小,7个字节。
//02:4/8   because:首元素地址。
//03:1     because:首元素。
//04:1     because:第二个元素。
//05:4/8   because:数组地址。
//06:4/8   because:跳过整个数组的地址。
//07:4/8   because:第二个元素的地址。

2.2.4 代码4

#include <stdio.h>

int main()
{
	char arr[] = "abcdef";
	printf("01:%zd\n", strlen(arr));
	printf("02:%zd\n", strlen(arr + 0));
	//printf("03:%zd\n", strlen(*arr));
	//printf("04:%zd\n", strlen(arr[1]));
	printf("05:%zd\n", strlen(&arr));
	printf("06:%zd\n", strlen(&arr + 1));
	printf("07:%zd\n", strlen(&arr[0] + 1));
	return 0;
}
运行:
016
026
056
0626
075

解析:

解析:
//01:6        because:6
//02:6        because:arr首元素的地址,arr+0还是首元素的地址。
//03:err      because:'a' ->97,err
//04:err      because:'b' ->98,err
//05:6        because:数组地址。
//06:unknown  because:跳过整个数组的地址。
//07:5        because:5

2.2.5 代码5

#include <stdio.h>

int main()
{
	char* p = "abcdef";
	printf("01:%zd\n", sizeof(p));
	printf("02:%zd\n", sizeof(p + 1));
	printf("03:%zd\n", sizeof(*p));
	printf("04:%zd\n", sizeof(p[0]));
	printf("05:%zd\n", sizeof(&p));
	printf("06:%zd\n", sizeof(&p + 1));
	printf("07:%zd\n", sizeof(&p[0] + 1));
	return 0;
}
运行(32位):
014
024
031
041
054
064
074
运行(64位):
018
028
031
041
058
068
078

解析:

解析:
//01:4/8      because:p是指针变量,计算指针变量的大小。
//02:4/8      because:b的地址。
//03:1        because:*p是char类型,1个字节。
//04:1        because:p[0] -> *(p+0) -> *p -> 'a' 大小1个字节。
//05:4/8      because:取出的是p的地址。
//06:4/8      because:跳过p指针变量后的地址。
//07:4/8      because:取出字符串首字符的地址,+1是第二个字符的地址。

2.2.6 代码6

#include <stdio.h>

int main()
{
	char* p = "abcdef";
	printf("01:%zd\n", strlen(p));
	printf("02:%zd\n", strlen(p + 1));
	//printf("03:%zd\n", strlen(*p));
	//printf("04:%zd\n", strlen(p[0]));
	printf("05:%zd\n", strlen(&p));
	printf("06:%zd\n", strlen(&p + 1));
	printf("07:%zd\n", strlen(&p[0] + 1));
	return 0;
}
运行:
016
025
053
0611
075

解析:

解析:
//01:6       because:传入首元素的地址。
//02:5       because:传入第二个元素的地址。
//03:err     because:'a' -> 97,err
//04:err     because:'a' -> 97,err
//05:unknown because:&p是指针变量p的地址,和字符串"abcdef"关系不大
// 从p这个指针变量的起始位置开始向后数的,p变量存放的地址是什么,不知道,因此随机值。
//06:unknown because:随机值
//07:5       because:第二个字符的地址。

2.3 二维数组

#include <stdio.h>

int main()
{
	int a[3][4] = { 0 };
	printf("01:%zd\n", sizeof(a));
	printf("02:%zd\n", sizeof(a[0][0]));
	printf("03:%zd\n", sizeof(a[0]));
	printf("04:%zd\n", sizeof(a[0] + 1));
	printf("05:%zd\n", sizeof(*(a[0] + 1)));
	printf("06:%zd\n", sizeof(a + 1));
	printf("07:%zd\n", sizeof(*(a + 1)));
	printf("08:%zd\n", sizeof(&a[0] + 1));
	printf("09:%zd\n", sizeof(*(&a[0] + 1)));
	printf("10:%zd\n", sizeof(*a));
	printf("11:%zd\n", sizeof(a[3]));
	return 0;
}
运行(32位):
0148
024
0316
044
054
064
0716
084
0916
1016
1116
运行(64位):
0148
024
0316
048
054
068
0716
088
0916
1016
1116

解析:

解析:
//01:48       because:数组的大小,48 = 3*4*sizeof(int)
//02:4        because:第一行第一个元素。
//03:16       because:第一行的数组名,单独放在sizeof内部了。
//04:4/8      because:a[0]第一行的数组名,但是a[0]并没有单独放在sizeof内部,
// 所以这里的数组名a[0]是数组首元素的地址,+1就是a[0][1]的地址。
//05:4        because:第一行第二个元素。
//06:4/8      because:a作为数组名并没有单独放在sizeof内部,a表示数组首元素的地址,
// 是二维数组首元素的地址,也就是第一行的地址,a+1跳过一行,指向第二行。
//07:16       because:a+1是第二行的地址,*(a+1)就是第二行,计算的是第二行的大小。
// *(a+1) == a[1],a[1]是第二行数组名。
//08:4/8      because:a[0]是第一行的数组名,&a[0]取出的是数组的地址,&a[0]+1就是第二行的地址。
//09:16       because:对第二行的地址解引用。
//10:16       because:a作为数组名并没有单独放在sizeof内部,所以a表示数组首元素的地址,是
// 二维数组首元素的地址,也就是第一行的地址,*a就是第一行,计算的是第一行的大小。
// *a == *(a+0) == a[0]
//11:16       because:a[3]无需真实存在,可以通过类型推断算出长度。a[3]是第四行的数组名。

3、指针运算笔试题解析

3.1 题目1

#include <stdio.h>  
int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));
	return 0;
}
运行:
2,5

画图解析:

3.2 题目2

//在X86环境下  
//假设结构体的大小是20个字节  
//程序输出的结构是啥?  
#include<stdio.h>
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000;
int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}
运行:
00100014
00100001
00100004

解析:

1、struct Test* p = (struct Test*)0x100000; // 将指针p强制指向内存地址 0x100000

2、printf("%p\n", p + 0x1);

  • 当对指针进行加法(如p+0x1)时,实际地址的偏移量 = 指针指向类型的大小 * 加数。
  • p是struct Test*类型,0x100000 + 0x1 * 20 = 0x100000+0x14 = 0x100014

3、printf("%p\n", (unsigned long)p + 0x1);

  • p被强制转化为unsigned long,此时是普通整数加法。

4、printf("%p\n", (unsigned int*)p + 0x1);

  • p被强制转化为unsigned int*,指针运算的单位是unsigned int的大小。

3.3 题目3

#include <stdio.h>  
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	int* p;  p = a[0];
	printf("%d", p[0]);
	return 0;
}
运行:
1

解析:

int* p = a[0];        // p 指向第一行首地址(即 &a[0][0])
printf("%d", p[0]);   // 访问 p[0] = a[0][0]

3.4 题目4

//假设环境是x86环境,程序输出的结果是啥?  
#include <stdio.h>  
int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}
运行:
FFFFFFFC,-4

解析:

  • a[4][2]是第四行第2列的元素:
地址 = a基址 + 4行偏移 + 2列偏移  
     = a + (4×5 + 2)×4 = a + 88 字节
  • p[4][2]是第4个int[4]数组的第2个元素:
地址 = p基址 + 4个数组偏移 + 2列偏移  
     = a + (4×4 + 2)×4  = a + 72 字节
  • 地址差
&p[4][2] - &a[4][2] = (a + 72) - (a + 88) = -16 字节
  • int为单位的:
-16 字节 / sizeof(int) = -4

输出解释:

  • 在%p格式中,-4的补码表示为0xFFFFFFFC(32位系统)。

3.5 题目5

#include <stdio.h>  
int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1);
	int* ptr2 = (int*)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}
运行:
10,5

3.6 题目6

#include <stdio.h>  
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}
运行:
at

3.7 题目7

#include <stdio.h>  
int main()
{
	char* c[] = { "ENTER","NEW","POINT","FIRST" };
	char** cp[] = { c + 3,c + 2,c + 1,c };
	char*** cpp = cp;
	printf("%s\n", **++cpp);
	printf("%s\n", *-- * ++cpp + 3);
	printf("%s\n", *cpp[-2] + 3);
	printf("%s\n", cpp[-1][-1] + 1);
	return 0;
}
运行:
POINT
ER
ST
EW


完。

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

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

相关文章

OpenCV 图形API(60)颜色空间转换-----将图像从 YUV 色彩空间转换为 RGB 色彩空间函数YUV2RGB()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将图像从 YUV 色彩空间转换为 RGB。 该函数将输入图像从 YUV 色彩空间转换为 RGB。Y、U 和 V 通道值的常规范围是 0 到 255。 输出图像必须是 8…

hbuilderx云打包生成的ipa文件如何上架

使用hbuilderx打包&#xff0c;会遇到一个问题。开发的ios应用&#xff0c;需要上架到app store&#xff0c;因此&#xff0c;就需要APP store的签名证书&#xff0c;并且还需要一个像xcode那样的工具来上架app store。 我们这篇文章说明下&#xff0c;如何在windows电脑&…

Golang | 位运算

位运算比常规运算快&#xff0c;常用于搜索引擎的筛选功能。例如&#xff0c;数字除以二等价于向右移位&#xff0c;位移运算比除法快。

产品动态|千眼狼sCMOS科学相机捕获单分子荧光信号

单分子荧光成像技术&#xff0c;作为生物分子动态研究的关键工具&#xff0c;对捕捉微弱信号要求严苛。传统EMCCD相机因成本高昂&#xff0c;动态范围有限&#xff0c;满阱容量低等问题&#xff0c;制约单分子研究成果产出效率。 千眼狼精准把握科研需求与趋势&#xff0c;自研…

Hot100方法及易错点总结2

本文旨在记录做hot100时遇到的问题及易错点 五、234.回文链表141.环形链表 六、142. 环形链表II21.合并两个有序链表2.两数相加19.删除链表的倒数第n个节点 七、24.两两交换链表中的节点25.K个一组翻转链表(坑点很多&#xff0c;必须多做几遍)138.随机链表的复制148.排序链表 N…

网络:手写HTTP

目录 一、HTTP是应用层协议 二、HTTP服务器 三、HTTP服务 认识请求中的uri HTTP支持默认首页 响应 功能完善 套接字复用 一、HTTP是应用层协议 HTTP下层是TCP协议&#xff0c;站在TCP的角度看&#xff0c;要提供的服务是HTTP服务。 这是在原来实现网络版计算器时&am…

【计算机视觉】CV实战项目 - 基于YOLOv5的人脸检测与关键点定位系统深度解析

基于YOLOv5的人脸检测与关键点定位系统深度解析 1. 技术背景与项目意义传统方案的局限性YOLOv5多任务方案的优势 2. 核心算法原理网络架构改进关键点回归分支损失函数设计 3. 实战指南&#xff1a;从环境搭建到模型应用环境配置数据准备数据格式要求数据目录结构 模型训练配置文…

【python】如何将python程序封装为cpython的库

python程序在发布时&#xff0c;往往会打包为cpython的库&#xff0c;并且根据应用服务器的不同架构&#xff08;x86/aarch64&#xff09;&#xff0c;以及python的不同版本&#xff0c;封装的输出类型也是非常多。本文介绍不同架构指定python下的代码打包方式&#xff1a; 首…

计算机组成原理 课后练习

例一&#xff1a; 例二&#xff1a; 1. 原码一位乘 基本原理 原码是一种直接表示数值符号和大小的方式&#xff1a;最高位为符号位&#xff08;0表示正&#xff0c;1表示负&#xff09;&#xff0c;其余位表示数值的绝对值。原码一位乘的核心思想是逐位相乘&#xff0c;并通…

SVN仓库突然没有权限访问

如果svn仓库突然出现无法访问的情况&#xff0c;提示没有权限&#xff0c;所有账号都是如此&#xff0c;新创建的账号也不行。 并且会突然提示要输入账号密码。 出现这个情况时&#xff0c;大概率库里面的文件有http或者https的字样&#xff0c;因为单独给该文件添加权限导致…

【Qt】文件

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Qt 目录 一&#xff1a;&#x1f525; Qt 文件概述 二&#xff1a;&#x1f525; 输入输出设备类 三&#xff1a;&#x1f525; 文件读写类 四&#xff1a;&#x1f525; 文件和目录信息类 五&…

【AI】[特殊字符]生产规模的向量数据库 Pinecone 使用指南

一、Pinecone 的介绍 Pinecone是一个完全托管的向量数据库服务&#xff0c;专为大规模机器学习应用设计。它允许开发者轻松存储、搜索和管理高维向量数据&#xff0c;为推荐系统、语义搜索、异常检测等应用提供强大的基础设施支持。 1.1 Pinecone的核心特性 1. 高性能向量搜…

dstream

DStream转换DStream 上的操作与 RDD 的类似&#xff0c;分为 Transformations&#xff08;转换&#xff09;和 Output Operations&#xff08;输出&#xff09;两种&#xff0c;此外转换操作中还有一些比较特殊的原语&#xff0c;如&#xff1a;updateStateByKey()、transform(…

HFSS5(李明洋)——设置激励(波端口激励)

Magnetic是适用于铁磁氧导体的&#xff0c;只有前三种激励类型可以用于计算S参数 1波端口激励 也可以设置在模型内部&#xff0c;如果是设置在模型内部必须加一段理想导体&#xff0c;用于指定端口方向 1.1——模式 number 输入N&#xff1a;计算1-N的模式都计算 1.2——模式…

ubiquant比赛系列——用docker准备ubipoker开发环境

比赛过程&#xff1a; 环境准备&#xff1a; #在云服务器上拉python官方的docker镜像并下载到本地 https://hub.docker.com/_/python/ sudo docker pull python:3.11.12-slim-bullseye sudo docker images sudo docker save -o 3.11.12-slim-bullseye.tar python:3.11.12-slim…

Rust实现高性能目录扫描工具ll的技术解析

Rust实现高性能目录扫描工具ll的技术解析 一、项目概述 本项目使用Rust构建了一个类ls命令行工具&#xff0c;具备以下核心特性&#xff1a; 多格式文件信息展示并行目录扫描加速人类可读文件大小运行时性能统计交互式进度提示 二、技术架构 1. 关键技术栈 clap&#xff…

深入理解C语言变量:从基础到实践

在编程世界中&#xff0c;变量是最基础也是最重要的概念之一。作为C语言的核心组成部分&#xff0c;变量承载着程序运行时数据的存储和传递功能。理解变量的工作原理和正确使用方法&#xff0c;是成为一名合格C程序员的必经之路。本文将全面介绍C语言变量的各个方面&#xff0c…

RK3562/3588 系列之0—NPU基础概念

RK3562/3588 系列之0—NPU基础概念 1.处理器分类2.算力衡量指标TOPS参考文献 1.处理器分类 中央处理器(CPU)&#xff1b; 图形处理器 (GPU)&#xff1b; 神经网络处理器(NPU)。 每个处理器擅长不同的任务:CPU擅长顺序控制和即时性&#xff1b;GPU适合并行数据流处理,NPU擅长…

canvas画板!随意画!!

希望你天天开心 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>绘画板</title…

Float32、Float16、BFloat16

我们先介绍 Float32、Float16、BFloat16 的 浮点数表示方法 然后根据浮点数表示&#xff0c;来分析总结他们是怎么控制 精度和 数值范围 的 最后再来对比的说明 Float32、Float16、BFloat16 的 应用场景 和 硬件支持 1、浮点数的表示方法 Float32 &#xff1a; 单精度浮点数…