10.C# —— 数组Array

目录

一、一维数组

[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. 数组操作

  • 修改元素:通过索引赋值(索引不能超出范围,否则报错)

    cs 复制代码
    string[] msgs = new string[100];
    msgs[0] = "张三";  // 正确
    // msgs[100] = "ss"; 错误!索引超出数组界限(最大索引99)
  • 循环赋值:批量给数组元素赋值

    cs 复制代码
    for (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索引]

    cs 复制代码
    Console.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);
    }
  • 批量赋值

    cs 复制代码
    string[,] 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

五、核心知识点总结

  1. 数组本质 :固定大小、同类型数据容器,继承自Array,索引从 0 开始;
  2. 一维数组:线性存储,for/foreach 遍历,支持 object 存储多类型;
  3. 多维数组 :矩阵结构,维度长度固定,用GetLength(维度索引)获取长度;
  4. 交错数组 :数组的数组,子数组长度可变,语法类型[][]
  5. 引用类型:数组是引用类型,赋值传地址,对象数组可存储自定义类,支持协变。
相关推荐
2601_9620725511 小时前
李梦娇常识4600问|题库|打印版
sql·华为od·华为·c#·华为云·.net·harmonyos
m0_5474866613 小时前
《C#语言程序设计与实践》 全套PPT课件
c语言·c#·c语言程序设计
叶帆14 小时前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
IT方大同15 小时前
(嵌入式操作系统)信号量
嵌入式硬件·c#
z落落15 小时前
C# FileStream文件流读取文件
开发语言·c#
yngsqq16 小时前
排版优化 异形排版
c#
苦学的罐头16 小时前
C# 协变与逆变深度解析:为什么 IEnumerable<T> 能转换,而 List<T> 不行?
开发语言·c#·list
FuckPatience17 小时前
使用ReactiveUI 前端绑定不生效
c#
天天代码码天天17 小时前
用 TensorRT 加速 PP-OCR:一套 C++ DLL + C# 调用的高性能 OCR 推理方案
c++·c#·ocr