C# 数组(Array)(手把手讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在编程世界中,数据的组织与管理是解决问题的核心能力之一。**C# 数组(Array)**作为基础数据结构,就像是程序员手中的“多功能工具箱”——它以简洁高效的方式存储和操作一组相同类型的数据。无论是处理学生成绩、游戏坐标,还是构建复杂算法,数组都是不可或缺的工具。本文将从零开始,通过实例与比喻,带您系统掌握 C# 数组的创建、操作及进阶用法,帮助您在实际开发中灵活运用这一核心概念。
一、数组的基本概念与特性
1.1 什么是数组?
数组可以被比喻为“带编号的抽屉”:每个抽屉(元素)按顺序排列,拥有唯一的编号(索引),并且所有抽屉必须存放相同类型的物品(数据类型)。在 C# 中,数组是一个固定长度的容器,用于存储同一类型的一组值。例如,一个整型数组可以存储多个整数,但无法同时存储字符串或浮点数。
核心特性:
- 固定长度:创建后无法动态扩容或缩容。
- 索引访问:通过数字索引(从 0 开始)快速定位元素。
- 类型统一:所有元素必须是相同的数据类型。
1.2 数组的内存模型
想象一个整齐排列的书架,每个书格(内存地址)对应一个元素。数组在内存中是连续存储的,这意味着访问元素时,计算机可以直接通过索引计算出内存地址,从而实现高效访问。例如,访问第 3 个元素时,只需通过 起始地址 + (索引 × 元素大小)
即可直接定位,无需遍历。
二、声明与初始化数组
2.1 声明数组的语法
声明数组时,需指定元素类型及方括号 []
:
int[] scores; // 声明一个整型数组,但未分配内存空间
string[] names;
2.2 初始化数组的三种方式
方法一:直接赋值
int[] numbers = new int[5]; // 创建包含 5 个整数的数组,默认值为 0
numbers[0] = 10; // 通过索引赋值
方法二:使用简写语法
double[] temperatures = { 36.5, 37.0, 36.8 }; // 自动推断长度为 3
方法三:混合声明与初始化
string[] fruits = new string[] { "Apple", "Banana", "Orange" };
2.3 实例:学生成绩管理
// 声明并初始化一个包含 3 个学生分数的数组
int[] studentScores = { 95, 88, 92 };
Console.WriteLine("第一个学生的分数:" + studentScores[0]); // 输出 95
三、访问与修改数组元素
3.1 索引访问的规则
- 索引从 0 开始:第一个元素的索引是
0
,最后一个元素的索引是Length - 1
。 - 越界访问:尝试访问不存在的索引(如
numbers[5]
在长度为 3 的数组中)会抛出IndexOutOfRangeException
。
示例代码:
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[0]); // 1
Console.WriteLine(numbers[numbers.Length - 1]); // 3
3.2 动态修改元素
string[] colors = { "Red", "Green", "Blue" };
colors[1] = "Yellow"; // 将第二个元素改为 "Yellow"
Console.WriteLine(colors[1]); // 输出 "Yellow"
四、遍历数组:逐个访问元素
4.1 使用 for 循环
int[] numbers = { 5, 10, 15, 20 };
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine("索引 " + i + " 的值:" + numbers[i]);
}
4.2 foreach 循环的优雅写法
foreach (int num in numbers)
{
Console.WriteLine(num);
}
// 注意:foreach 无法修改元素值,因为索引不可见
4.3 实战案例:计算平均分
double[] scores = { 85.5, 90.0, 78.5 };
double sum = 0;
foreach (double score in scores)
{
sum += score;
}
double average = sum / scores.Length;
Console.WriteLine("平均分:" + average); // 输出 (85.5+90+78.5)/3 = 84.666...
五、多维数组与交错数组
5.1 多维数组:矩阵的存储
多维数组可以看作“数组的数组”,常用于表示表格或棋盘:
int[,] matrix = new int[2, 3]; // 2 行 3 列的二维数组
matrix[0, 0] = 1; // 第一行第一列
matrix[1, 2] = 6; // 第二行第三列
// 遍历二维数组
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(1); col++)
{
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
5.2 交错数组(Jagged Arrays)
交错数组是“数组的数组”,但每一维的长度可以不同,类似“书架中每个抽屉的大小不同”:
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2 }; // 第一个元素有 2 个元素
jagged[1] = new int[] { 3, 4, 5 }; // 第二个元素有 3 个元素
六、数组的局限性与替代方案
6.1 数组的不足
- 固定长度:创建后无法动态调整大小,若需频繁增删元素,可能效率低下。
- 类型单一:无法混合存储不同数据类型(如同时包含整数和字符串)。
6.2 替代方案:动态数组 List
List<int> dynamicNumbers = new List<int>();
dynamicNumbers.Add(10); // 动态添加元素
dynamicNumbers.RemoveAt(0); // 删除元素
七、进阶技巧与常见场景
7.1 数组排序与搜索
int[] numbers = { 3, 1, 4, 1, 5 };
Array.Sort(numbers); // 排序后:1, 1, 3, 4, 5
int index = Array.BinarySearch(numbers, 3); // 返回索引 2
7.2 复制与合并数组
int[] arr1 = { 1, 2 };
int[] arr2 = new int[3];
Array.Copy(arr1, arr2, 2); // 将 arr1 的前 2 个元素复制到 arr2
八、常见问题解答
Q1:如何获取数组的长度?
int length = numbers.Length; // 适用于一维数组
int rows = matrix.GetLength(0); // 获取二维数组的行数
Q2:如何避免索引越界?
- 始终在访问前检查索引范围:
if (index >= 0 && index < array.Length)
。 - 使用
foreach
循环遍历时,无需手动管理索引。
结论
通过本文,我们系统学习了 C# 数组(Array) 的核心概念、操作方法及应用场景。数组以其高效、简洁的特点,成为处理同质化数据的基石。无论是基础的数据遍历、排序,还是多维数组的复杂结构,掌握数组的底层逻辑与代码实现,将帮助开发者在算法设计、游戏开发、数据处理等领域游刃有余。
当遇到动态需求时,可结合 List<T>
等动态集合类灵活应对。希望本文能成为您 C# 学习路上的“指南针”,助您在代码世界中构建更有序、高效的数据结构!