UE4性能观察的基础

2024-09-06 23:38
文章标签 基础 ue4 性能 观察

本文主要是介绍UE4性能观察的基础,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目标

关于性能分析,官方给出了些文档:
《性能及分析 | Unreal Engine Documentation》是一个目录,收集了相关的文档。
《性能与概要分析概述 | Unreal Engine Documentation》是一个整体的指南。

不过,我想从自己的思路出发讨论这个问题,收集相关资料并尝试其中的工具。所讨论的内容不限于官方文档。

讨论“游戏性能观察”

粗略来讲,我觉得“性能”可以分为时间方面和空间方面;分为CPU方面和GPU方面。

-时间空间
CPU运行在CPU上的逻辑(游戏逻辑、调用图形API、引擎框架逻辑等)内存
GPU执行图形API显存

对于其中每一个分类,我的思路都是:

  1. 首先,我需要有方法知道当前的总数值。例如,每一帧花费在CPU、GPU上的时间总共是多少,能不能达到30fps/60fps的目标?例如,内存总共占用了多少,显存总共占用了多少,他们到达了限制吗?这样才能知道哪个方面是需要重点关注的,而哪个方面是暂时不需要关注的。
  2. 理想状态下,是知道上面的总数值是是由哪些精确的因素构成。然而因素是很多的,往往没有办法轻易掌握。一些【工具】可以帮助我分析,比如以整齐的排版或可视化的图形来表示出信息。当然了,提升相关的【知识】也能提供重要的帮助。
  3. 虽然精确的因素不能全部掌握,但是存在一些方便观察,容易理解,但又占重要地位的因素。例如,“渲染”是游戏性能最常讨论的话题,而有一些因素是常常用来衡量渲染性能的,如“DrawCall数量”、“顶点数量”等。这些因素是最优先要观察的。

1. 使用“stat unit”观察帧时间瓶颈

在Cmd中输入stat unit,便可以输出一帧中的各方面处理时间:
在这里插入图片描述
在《如何改善虚幻引擎中的游戏线程CPU性能表现》中,有对这些时间做如下描述:

  • Frame(帧)时间指的是生成游戏中每一帧所需要花费的总体时间。 由于在完成一帧前会同时同步游戏线程渲染线程Frame时间常常接近于这些线程中的某一个时间。
  • GPU时间衡量的是显卡需要多长时间来渲染场景。 由于GPU时间与帧同步,它的值很可能也类似于Frame时间。
  • 如果Frame时间非常接近于Game时间,那么瓶颈是游戏线程。 如果Frame时间非常接近于Draw时间,那么您的瓶颈是渲染线程。 如果GameDraw都不怎么接近Frame,那么瓶颈就是显卡。

从官方的描述可以知道:Game对应游戏线程Draw对应渲染线程GPU对应显卡执行的时间。
不过其中令我感到些许困惑的是DrawGPU的区分。按照我的理解:首先,Draw虽然叫“渲染线程”,但实际上还是运行在CPU上的(这点基本确定);但差别在于,Draw时间是调用图形API,而GPU时间是执行图形API。虽说只是“调用”,但由于牵扯到渲染状态的切换等和GPU的交流,因此时间上还是有不小的消耗;反而是GPU的“执行”的时间很多时候比想象中小。(此处的看法不太确定,待后续学习)
关于渲染线程,可以查阅官方文档,例如《线程渲染 | Unreal Engine Documentation》和《并行渲染概述 | Unreal Engine Documentation》

2. 使用【Session Frontend】观察CPU中的时间

【Session Frontend】是UE4内置的一个开发者工具,详细的介绍见官方文档《分析工具参考 | Unreal Engine Documentation》。
这里,我结合《如何改善虚幻引擎中的游戏线程CPU性能表现》中的内容,尝试使用一下这个工具。

2.1 获得分析文件

首先,在运行游戏的时候,输入Cmd(可以按~键打开Cmd),输入stat startfile
在这里插入图片描述
随后就可以看到视窗左上角有显示文件已经录制的时间和当前的大小
在这里插入图片描述
然后,运行一段时间后(建议超过10秒,但不建议超过30分钟否则文件太大)stat stopfile
随后,就可以在项目目录/Saved/Profiling/UnrealStats/下找到刚才采集的信息
在这里插入图片描述

2.2 读取分析文件

打开“Session Frontend”(中文翻译为“会话前端”)
在这里插入图片描述
进入Profiler分页,点击Load
在这里插入图片描述
选择刚才的分析文件
在这里插入图片描述

2.3 观察分析文件中的数据

其中最重要的数据,要算底部的“ function tree”了:
在这里插入图片描述
内容很多,看来要想完全掌握问题,要依赖于自己掌握的“知识”了。


有一点要注意的是不要被“CPU Stall”(CPU停滞时间)迷惑,它们显示的是线程等待处理其他内容时所花费的时间,所以不需要关注。
在这里插入图片描述


其中一个重要的项目是FTickFunctionTask。 此项目下是正在更新的每个actor和组件。
在这里插入图片描述
如果游戏中存在着永不更新的actor,则可以在构造函数中:

PrimaryActorTick.bCanEverTick = false;

这样就可以完全防止其更新。

如果actor仅在某些时候进行更新,则可以在构造函数中:

PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = false;

然后可以使用SetActorTickEnabled函数来启用和禁用更新。

3. 使用【GPU Visualizer】观察GPU中的时间

在Cmd中输入ProfileGPU(或者快捷键Ctrl+Shift+,)可以打开【GPU Visualizer】
其中图形化地显示了各个部分所消耗的时间:
在这里插入图片描述
官方文档《GPU Profiling | Unreal Engine Documentation》中有讨论了其中的几项。

4. 使用“MemReport”观察内存

MemReport命令可以用来观察内存情况。不过我并没有在官方文档中发现对其专门的详细介绍,只在《在虚幻引擎 4 中处理内存泄漏问题 - Unreal Engine》和《Debugging and Optimizing Memory - Unreal Engine》找到对它的讨论。接下来我将在这两个文档的指导下试用这个功能。

4.1 输出报告

运行游戏,在Cmd中输入memreport获取报告,或者memreport -Full表示“更加完整”的报告。
报告将存在项目目录/Saved/Profiling/MemReports/中:
在这里插入图片描述

4.2 阅读报告

这些.memreport的文件是简单的文本文件,可以直接打开。
一个memreport -Full生成的报告如下:(省略了列表中中间的项目)

CommandLine Options: 
Time Since Boot: 55.12 SecondsPlatform Memory Stats for Windows
Process Physical Memory: 1026.80 MB used, 1047.58 MB peak
Process Virtual Memory: 1473.69 MB used, 1588.78 MB peak
Physical Memory: 5037.77 MB used,  11255.99 MB free, 16293.75 MB total
Virtual Memory: 8146.50 MB used,  134209584.00 MB free, 134217728.00 MB totalAllocator Stats for TBB: (not implemented)
Memory Stats:
FMemStack (gamethread) current size = 0.00 MB
FPageAllocator (all threads) allocation size [used/ unused] = [0.19 / 0.00] MB
Nametable memory usage = 6.45 MB
AssetRegistry memory usage = 37.47 MB49056  -  Light interaction memory - STAT_LightInteractionMemory - STATGROUP_SceneMemory - STATCAT_Advanced521136  -  Rendering mem stack memory - STAT_RenderingMemStackMemory - STATGROUP_SceneMemory - STATCAT_Advanced
//省略...            66142836  -  TEXTUREGROUP_World - STAT_TEXTUREGROUP_World - STATGROUP_TextureGroup - STATCAT_AdvancedObj List: -alphasort
Objects:Class    Count      NumKB      MaxKB   ResExcKB  ResExcDedSysKB  ResExcShrSysKB  ResExcDedVidKB  ResExcShrVidKB     ResExcUnkKBAbcImportSettings        1       0.16       0.16       0.00            0.00            0.00            0.00            0.00            0.00AbstractNavData        2       2.52       2.52       0.00            0.00            0.00            0.00            0.00            0.00
//省略...                                                                             WorldThumbnailRenderer        1       0.07       0.07       0.00            0.00            0.00            0.00            0.00            0.0022018 Objects (Total: 37.017M / Max: 42.880M / Res: 110.862M | ResDedSys: 16.665M / ResShrSys: 0.000M / ResDedVid: 86.493M / ResShrVid: 0.000M / ResUnknown: 7.704M)RHI resource memory (not tracked by our allocator)13104462  -  Render target memory 3D - STAT_RenderTargetMemory3D - STATGROUP_RHI - STATCAT_Advanced994184  -  Structured buffer memory - STAT_StructuredBufferMemory - STATGROUP_RHI - STATCAT_Advanced
//省略... 9574886  -  Vertex buffer memory - STAT_VertexBufferMemory - STATGROUP_RHI - STATCAT_Advanced
483.631MB totalLevels:
->  /Game/Maps/UEDPIE_0_ExampleProjectWelcomeListing spawned actors in persistent level:
Total: 76
TimeUnseen,TimeAlive,Distance,Class,Name,Owner6.44,  6.44,    1260,AbstractNavData,AbstractNavData-Default,None6.44,  6.44,    1260,CameraActor,CameraActor_0,PlayerCameraManager_0
//省略... 6.44,  6.44,    1260,PlayerState,PlayerState_0,PhysicsDemoPlayerController_C_0Particle Dynamic Memory Stats
Type,Count,MaxCount,Mem(Bytes),MaxMem(Bytes),GTMem(Bytes),GTMemMax(Bytes)
Total PSysComponents,0,0,0,0,0,0
Total DynamicEmitters,0,0,0,0,0,0
//省略... 
Mesh,0,0
TotalMemory Taken in Pool: 0
ACTIVE,0
TotalMemory Taken by Actives: 0
Particle Order Pool Stats0 entries for     0 bytesConfig cache memory usage:FileName         NumBytes         MaxBytesE:/UnrealProjects/ContentSamples425/Saved/Config/Windows/Engine.ini           745980           845156E:/UnrealProjects/ContentSamples425/Saved/Config/Windows/EditorPerProjectUserSettings.ini           412614           463008
//省略...      ../../../Engine/Config/ConsoleVariables.ini              500              572Total          3348660          3697386Pooled Render Targets:0.250MB  256x 256           1mip(s) HZBResultsCPU (B8G8R8A8)  0.250MB  256x 256           1mip(s) HZBResultsCPU (B8G8R8A8)  
//省略... 5.272MB 1208x 572           1mip(s) TemporalAA (FloatRGBA)  
196.558MB total, 113.018MB used, 93 render targets
Deferred Render Targets:
0.000MB Deferred totalListing all textures.
MaxAllowedSize: Width x Height (Size in KB, Authored Bias), Current/InMem: Width x Height (Size in KB), Format, LODGroup, Name, Streaming, Usage Count
2048x2048 (32768 KB, 0), 2048x2048 (32768 KB), PF_FloatRGBA, TEXTUREGROUP_World, /Engine/EngineMaterials/DefaultBloomKernel.DefaultBloomKernel, NO, 0
0x0 (16384 KB, 0), 0x0 (16384 KB), PF_FloatRGBA, TEXTUREGROUP_World, /Engine/MapTemplates/Sky/DaylightAmbientCubemap.DaylightAmbientCubemap, NO, 0
//省略... 
0x0 (0 KB, 0), 0x0 (0 KB), PF_Unknown, TEXTUREGROUP_World, /Script/LevelSequence.Default__LevelSequenceMediaController:MediaComponent.MediaTexture, NO, 0
Total size: InMem= 86.50 MB  OnDisk= 138.21 MB  Count=146, CountApplicableToMin=69
Total PF_Unknown size: InMem= 0.01 MB  OnDisk= 0.01 MB 
Total PF_B8G8R8A8 size: InMem= 14.53 MB  OnDisk= 20.57 MB 
//省略... 
Total TEXTUREGROUP_Bokeh size: InMem= 0.04 MB  OnDisk= 0.35 MB Listing all sounds:0.00 Kb for 0 resident soundsParticleSystems:
Size,Name,PSysSize,ModuleSize,ComponentSize,ComponentCount,CompResSize,CompTrueResSize2512,/Game/ExampleContent/Blueprints/P_Impact_Ripple.P_Impact_Ripple,552,1960,0,0,0,02512,Total,552,1960,0,0,0,0Obj List: class=SoundWave -alphasort
Objects:Object      NumKB      MaxKB   ResExcKB  ResExcDedSysKB  ResExcShrSysKB  ResExcDedVidKB  ResExcShrVidKB     ResExcUnkKBSoundWave /Engine/EditorSounds/Notifications/CompileFailed.CompileFailed       1.32       1.32      10.83           10.83            0.00            0.00            0.00            0.00SoundWave /Engine/EditorSounds/Notifications/CompileSuccess.CompileSuccess       1.33       1.33      11.04           11.04            0.00            0.00            0.00            0.00Class    Count      NumKB      MaxKB   ResExcKB  ResExcDedSysKB  ResExcShrSysKB  ResExcDedVidKB  ResExcShrVidKB     ResExcUnkKBSoundWave        2       2.65       2.65      21.87           21.87            0.00            0.00            0.00            0.002 Objects (Total: 0.003M / Max: 0.003M / Res: 0.021M | ResDedSys: 0.021M / ResShrSys: 0.000M / ResDedVid: 0.000M / ResShrVid: 0.000M / ResUnknown: 0.000M)Obj List: class=SkeletalMesh -alphasort
Objects:Object      NumKB      MaxKB   ResExcKB  ResExcDedSysKB  ResExcShrSysKB  ResExcDedVidKB  ResExcShrVidKB     ResExcUnkKBSkeletalMesh /Game/Character/HeroTPP.HeroTPP     659.01     686.32     323.36           21.78            0.00            0.00            0.00          301.57Class    Count      NumKB      MaxKB   ResExcKB  ResExcDedSysKB  ResExcShrSysKB  ResExcDedVidKB  ResExcShrVidKB     ResExcUnkKBSkeletalMesh        1     659.01     686.32     323.36           21.78            0.00            0.00            0.00          301.571 Objects (Total: 0.644M / Max: 0.670M / Res: 0.316M | ResDedSys: 0.021M / ResShrSys: 0.000M / ResDedVid: 0.000M / ResShrVid: 0.000M / ResUnknown: 0.295M)
//省略... 

值得一提的是,用 【差异工具】 很有用,因为它们经过排序,因此可以正确区分。


报告的第一部分列出了整体内存使用情况,以及有关特定于平台的内存使用情况。

Platform Memory Stats for Windows
Process Physical Memory: 1026.80 MB used, 1047.58 MB peak
Process Virtual Memory: 1473.69 MB used, 1588.78 MB peak
Physical Memory: 5037.77 MB used,  11255.99 MB free, 16293.75 MB total
Virtual Memory: 8146.50 MB used,  134209584.00 MB free, 134217728.00 MB total

随后,是已经注册的统计信息:

Allocator Stats for TBB: (not implemented)
Memory Stats:
FMemStack (gamethread) current size = 0.00 MB
FPageAllocator (all threads) allocation size [used/ unused] = [0.19 / 0.00] MB
Nametable memory usage = 6.45 MB
AssetRegistry memory usage = 37.47 MB49056  -  Light interaction memory - STAT_LightInteractionMemory - STATGROUP_SceneMemory - STATCAT_Advanced521136  -  Rendering mem stack memory - STAT_RenderingMemStackMemory - STATGROUP_SceneMemory - STATCAT_Advanced
//省略...            66142836  -  TEXTUREGROUP_World - STAT_TEXTUREGROUP_World - STATGROUP_TextureGroup - STATCAT_Advanced

对于其中的每一项,例如Light interaction memory,可以在源代码中搜索STAT_LightInteractionMemory来获得更详细的信息:
在这里插入图片描述


接下来是Obj List: -alphasort(以字母排序的物体的列表)

Obj List: -alphasort
Objects:Class    Count      NumKB      MaxKB   ResExcKB  ResExcDedSysKB  ResExcShrSysKB  ResExcDedVidKB  ResExcShrVidKB     ResExcUnkKBAbcImportSettings        1       0.16       0.16       0.00            0.00            0.00            0.00            0.00            0.00AbstractNavData        2       2.52       2.52       0.00            0.00            0.00            0.00            0.00            0.00
//省略...                                                                             WorldThumbnailRenderer        1       0.07       0.07       0.00            0.00            0.00            0.00            0.00            0.0022018 Objects (Total: 37.017M / Max: 42.880M / Res: 110.862M | ResDedSys: 16.665M / ResShrSys: 0.000M / ResDedVid: 86.493M / ResShrVid: 0.000M / ResUnknown: 7.704M)

它显示了每一类UObject以及它们使用了多少内存。


接下来是渲染内存

RHI resource memory (not tracked by our allocator)13104462  -  Render target memory 3D - STAT_RenderTargetMemory3D - STATGROUP_RHI - STATCAT_Advanced994184  -  Structured buffer memory - STAT_StructuredBufferMemory - STATGROUP_RHI - STATCAT_Advanced
//省略... 9574886  -  Vertex buffer memory - STAT_VertexBufferMemory - STATGROUP_RHI - STATCAT_Advanced
483.631MB total

接下来是Streaming Levels

Levels:
->  /Game/Maps/UEDPIE_0_ExampleProjectWelcome

接下来是关卡中生成的Actors:

Listing spawned actors in persistent level:
Total: 76
TimeUnseen,TimeAlive,Distance,Class,Name,Owner6.44,  6.44,    1260,AbstractNavData,AbstractNavData-Default,None6.44,  6.44,    1260,CameraActor,CameraActor_0,PlayerCameraManager_0
//省略... 6.44,  6.44,    1260,PlayerState,PlayerState_0,PhysicsDemoPlayerController_C_0

5. 切换 视图模式 来观察渲染方面的数据

在关卡编辑器中可以切换【视图模式】:
在这里插入图片描述

5.1 网格模式(Brush Wireframe)

在这里插入图片描述
网格模式可以观察当前顶点的情况。可以观察到哪个部分的顶点过于密集,这可能代表着那个模型需要做LOD。

5.2 着色器复杂度(Shader Complexity)

在这里插入图片描述
着色器复杂度可以观察到哪部分花费了太多的像素着色器工作量,对于数值较高的部分,需要衡量下达到的效果和所耗费的性能了。

6. 使用一些统计命令(stat …)观察一些渲染相关数据

6.1 三角形数目

stat engine命令:
在这里插入图片描述
可以显示一些三角形数目,例如Static Mesh Tris代表了StaticMesh的三角形数目

6.2 Draw Call

stat SceneRendering命令:
在这里插入图片描述

7. 在材质编辑器内查看材质的相关数据

在这里插入图片描述
可以显示指令数Sampler数目 等等。。。

8. 使用【统计数据】窗口

在这里插入图片描述
有多个分类:
在这里插入图片描述
比如“Primitive统计数据”:
在这里插入图片描述

其他工具

1)其他 Stat命令

所有的统计数据可以在这里找到:
在这里插入图片描述
《Stat命令 | Unreal Engine Documentation》中有对其中进行介绍。

2)使用【MallocProfiler】观察内存

关于这个工具并没有找到官方文档,但在《UE4内存Profiler - 知乎》中有其讨论。

3)英特尔® 图形性能分析器

英特尔提供了免费的图形分析器:Intel® Graphics Performance Analyzers
官方教程文档见:《Unreal Engine 4 优化教程 第一部分》

4)RenderDoc

RenderDoc在UE4中使用的官方文档:《RenderDoc | Unreal Engine Documentation》

5)Unreal Insights

《Unreal Insights | Unreal Engine Documentation》

官方的建议

官方文档《写给美术师和设计师的性能指南 | Unreal Engine Documentation》为非技术人员从一般角度提出了些建议,我觉得很有参考价值。

《粒子系统的核心优化概念 | Unreal Engine Documentation》中有针对于粒子系统的优化建议。

其他问题与未来学习的方向

1)显存怎么看?

我发现GPU-Z中可以看到当前计算机显卡的整体显存:
在这里插入图片描述
不过这是一个总体的值,并没有区别UE4引擎所消耗的。
那么如何正确的观察UE4游戏所消耗的显存呢?更进一步,有办法知道显存的具体的分配情况吗?

2)游戏线程、渲染线程、GPU之间的同步

《并行渲染概述 | Unreal Engine Documentation》

这篇关于UE4性能观察的基础的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143444

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou