目录
[1. 数组定义](#1. 数组定义)
[2. 数组赋值(4 种常用方式)](#2. 数组赋值(4 种常用方式))
[3. 数组操作](#3. 数组操作)
[4. for vs foreach 区别](#4. for vs foreach 区别)
[5. object 数组(存储不同类型数据)](#5. object 数组(存储不同类型数据))
[1. 多维数组定义](#1. 多维数组定义)
[2. 核心属性(获取数组信息)](#2. 核心属性(获取数组信息))
[3. 数组操作](#3. 数组操作)
[1. 交错数组定义](#1. 交错数组定义)
[2. 数组操作](#2. 数组操作)
[交错数组 vs 多维数组](#交错数组 vs 多维数组)
[1. 数组的引用传递](#1. 数组的引用传递)
[2. 存储自定义对象数组](#2. 存储自定义对象数组)
[3. 数组协变(父类数组存储子类对象)](#3. 数组协变(父类数组存储子类对象))
[4. 实用工具:string.Join](#4. 实用工具:string.Join)
数组 是存储相同类型数据 的固定大小容器,所有数组都继承自 System.Array,通过索引(下标,从 0 开始) 操作元素,最大索引 = 数组长度 - 1。
一、一维数组
一维数组是最基础的数组类型,用于存储线性的同类型数据,定义、赋值、遍历是核心操作。
1. 数组定义
语法:数据类型[] 变量名;(变量名建议加后缀s)
cs
int[] ages; // 整型数组,默认值 0
bool[] sexs; // 布尔数组,默认值 false
string[] names; // 字符串数组,默认值 null
char[] chars; // 字符数组,默认值 \0
2. 数组赋值(4 种常用方式)
cs
// 1. 仅指定长度,创建空数组
ages = new int[10];
// 2. 指定长度 + 初始化元素(长度必须和元素个数一致)
names = new string[5] {"张三", "李四", "王五", "赵六", "孙七"};
// 3. 不指定长度,由元素个数自动推导
ages = new int[] { 1, 2, 3 };
// 4. 字面量简化定义(最常用)
int[] nums = { 1, 2, 3 };
3. 数组操作
-
修改元素:通过索引赋值(索引不能超出范围,否则报错)
csstring[] msgs = new string[100]; msgs[0] = "张三"; // 正确 // msgs[100] = "ss"; 错误!索引超出数组界限(最大索引99) -
循环赋值:批量给数组元素赋值
csfor (int i = 0; i < msgs.Length; i++) // Length:数组长度属性 { msgs[i] = i + "深度"; } -
获取元素:单个获取 + 批量遍历
cs// 单个获取(通过索引) Console.WriteLine(msgs[99]); // 方式1:for循环遍历(可获取索引,支持修改元素) for (int i = 0; i < msgs.Length; i++) { Console.WriteLine(msgs[i] + "--------"); } // 方式2:foreach遍历(语法简单,仅读取元素,无法获取索引) foreach (string item in msgs) { Console.WriteLine(item + "++++"); }
4. for vs foreach 区别
- for:灵活,可通过索引访问 / 修改元素,能获取元素位置;
- foreach :语法简洁,仅用于读取元素,无法获取索引、不能修改元素位置。
5. object 数组(存储不同类型数据)
object 是 C# 所有类型的基类,可存储任意类型数据(开发中优先用泛型,此方式了解即可):
cs
object[] arr = new object[5] {1, 2, 3, "张三", true};
foreach (object item in arr)
{
Console.WriteLine(item); // 输出:1、2、3、张三、true
}
二、多维数组
多维数组是矩阵式结构 (如二维数组 = 几行几列),每个维度长度固定,支持二维、三维及更高维度。
1. 多维数组定义
- 二维数组:
数据类型[,] 变量名; - 三维数组:
数据类型[,,] 变量名; - N 维数组:
数据类型[N-1个逗号] 变量名;
cs
// 1. 指定维度长度(创建空数组)
int[,] ints = new int[2,3]; // 2行3列二维数组
int[,,] ints1 = new int[2,3,4]; // 三维数组
// 2. 不指定长度,自动推导(常用)
int[,] ints = new int[,]
{
{1,2,3 }, // 第0行
{4,5,6}, // 第1行
{7,8,9}, // 第2行
};
2. 核心属性(获取数组信息)
cs
string[,] strings = new string[,]
{
{"孙悟空","猪八戒","沙和尚" },
{"刘备","曹操","孙权" }
};
Console.WriteLine(strings.Length); // 总元素个数:6
Console.WriteLine(strings.Rank); // 维度数:2
Console.WriteLine(strings.GetLength(0));// 第0维度长度(行数):2
Console.WriteLine(strings.GetLength(1));// 第1维度长度(列数):3
3. 数组操作
-
获取 / 修改元素 :
数组名[维度1索引, 维度2索引]csConsole.WriteLine(strings[0,0]); // 输出:孙悟空 strings[1,1] = "曹孟德"; // 修改第1行第1列元素 -
循环遍历:嵌套 for 循环(按维度遍历)
cs// 遍历行(第0维度) for (int i = 0; i < strings.GetLength(0); i++) { // 遍历列(第1维度) for (int j = 0; j < strings.GetLength(1); j++) { Console.Write(strings[i,j] + " "); } Console.WriteLine(); // 换行 } // foreach遍历(直接读取所有元素,无视维度) foreach (var item in strings) { Console.WriteLine(item); } -
批量赋值
csstring[,] names = new string[5, 10]; // 5行10列空数组 for (int i= 0; i<names.GetLength(0); i++) { for (int j = 0; j < names.GetLength(1); j++) { names[i, j] = $"行:{i} 列:{j}"; } }
三、交错数组
交错数组是数组的数组 (大数组包含小数组),每个小数组长度可以不同(这是和多维数组的核心区别)。
1. 交错数组定义
语法:数据类型[][] 变量名 = new 数据类型[][]{ 小数组1, 小数组2... };
cs
// 定义两个长度不同的一维数组
int[] i1s = new int[4] {1,2,3,4}; // 长度4
int[] i2s = new int[] {1,2,3,4,5}; // 长度5
// 交错数组(大数组包含3个小数组,长度各不相同)
int[][] ints = new int[][]
{
i1s,
i2s,
new int[]{1,2,3,4,5,999} // 长度6
};
2. 数组操作
-
获取 / 修改元素 :
大数组[外层索引][内层索引]cs// 分步取值 int[] arr = ints[1]; // 获取第1个小数组 int a = arr[4]; // 输出:5 // 一步取值 Console.WriteLine(ints[2][5]); // 输出:999 // 修改元素 ints[1][2] = 888; -
循环遍历:嵌套循环(先遍历大数组,再遍历小数组)
cs// for循环遍历 for (int i = 0; i < ints.Length; i++) // 遍历外层大数组 { for (int j = 0; j < ints[i].Length; j++) // 遍历内层小数组 { Console.WriteLine($"({i}:{j}={ints[i][j]})"); } } // foreach遍历 foreach (int[] item in ints) // 先遍历外层数组 { foreach (int item1 in item) // 再遍历内层数组 { Console.WriteLine(item1); } }
交错数组 vs 多维数组
| 类型 | 结构特点 | 子数组长度 |
|---|---|---|
| 多维数组 | 矩阵式固定结构 | 必须相同 |
| 交错数组 | 数组嵌套,灵活结构 | 可以不同 |
四、数组存储引用类型
数组本身是引用类型 ,存储自定义对象(引用类型)时,核心理解引用传递 和对象数组。
1. 数组的引用传递
数组赋值是传递引用地址,而非复制数据,修改原数组,赋值后的数组也会同步变化:
cs
int[] arr = new int[] { 1, 2, 3 };
int[] arr2 = arr; // 赋值(传递引用)
arr[0] = 999; // 修改原数组
Console.WriteLine(arr2[0]); // 输出:999(同步变化)
2. 存储自定义对象数组
先定义类,再创建该类的数组,批量存储对象:
cs
// 1. 定义自定义类
public class People
{
public string Name { get; set; } // 属性
}
// 2. 创建对象数组并赋值
People[] p1s = new People[10]; // 长度为10的People数组
for (int i = 0; i < p1s.Length; i++)
{
// 创建对象并赋值
People p1 = new People() { Name = "学生" + i };
p1s[i] = p1; // 存入数组
}
// 3. 遍历对象数组
foreach (People p in p1s)
{
Console.WriteLine(p.Name);
}
3. 数组协变(父类数组存储子类对象)
如果子类继承父类,父类数组可以存储子类对象(协变):
cs
// 子类继承父类
public class Student : People { }
// 父类数组存储父类+子类对象
People[] ps = new People[]
{
new People(){Name="张三"},
new Student(){Name="李四"} // 子类对象存入父类数组
};
4. 实用工具:string.Join
快速将数组元素拼接为字符串,指定分隔符:
cs
int[] arr = {999,2,3};
Console.WriteLine(string.Join("-", arr)); // 输出:999-2-3
五、核心知识点总结
- 数组本质 :固定大小、同类型数据容器,继承自
Array,索引从 0 开始; - 一维数组:线性存储,for/foreach 遍历,支持 object 存储多类型;
- 多维数组 :矩阵结构,维度长度固定,用
GetLength(维度索引)获取长度; - 交错数组 :数组的数组,子数组长度可变,语法
类型[][]; - 引用类型:数组是引用类型,赋值传地址,对象数组可存储自定义类,支持协变。