当前位置: 首页 > article >正文

C#中的数组

C#中的数组介绍

在 C# 中,数组是一种数据结构,用于存储固定大小的相同类型的元素集合。数组可以是一维的,也可以是多维的(例如二维、三维等)。数组在声明时必须指定元素的类型,并且一旦创建,其大小就是固定的。

一维数组

一维数组是最基础的数组形式,它包含一个元素序列。

声明和初始化一维数组:

int[] array = new int[5]; // 创建一个包含5个整数的数组,初始值默认为0
array[0] = 10;
array[1] = 20;
// ...
​
// 直接初始化
int[] array2 = { 10, 20, 30, 40, 50 };

多维数组

多维数组可以视为数组的数组,例如二维数组可以视为行和列的集合。

声明和初始化二维数组:

int[,] array2D = new int[3, 4]; // 创建一个3行4列的二维整数数组
array2D[0, 0] = 1;
array2D[0, 1] = 2;
// ...
​
// 直接初始化
int[,] array2D = {
    { 1, 2, 3, 4 },
    { 5, 6, 7, 8 },
    { 9, 10, 11, 12 }
};

数组的特性

  • 长度:数组有一个 Length 属性,它返回数组中元素的总数。

  • 固定大小:数组的大小在创建后不能改变。

  • 零基索引:数组的索引从 0 开始。

  • 类型安全:数组的元素必须是声明时指定的类型或其派生类型。

数组的方法

数组类型 System.Array 提供了一些有用的方法,例如:

  • Clone():创建数组的浅表副本。

  • CopyTo():将数组的元素复制到另一个数组。

  • Resize():改变数组的大小(需要 System.Collections.Generic 命名空间中的 List<T> 类)。

遍历数组

可以使用 for 循环或 foreach 循环来遍历数组中的所有元素。

使用 for 循环:

for (int i = 0; i < array.Length; i++)
{
    Console.WriteLine(array[i]);
}

使用 foreach 循环:

foreach (int element in array)
{
    Console.WriteLine(element);
}

数组的内存管理

数组是引用类型,它们在托管堆上分配内存。当数组不再被引用时,它们会成为垃圾回收的候选对象。

C#中的数组的常用方法

在 C# 中,数组是内置的数据结构,提供了一些常用的方法来操作数组。这些方法大多数定义在 System.Array 类中,该类是所有数组类型的基类。以下是一些常用的数组方法:

  1. Clone()

    • 创建数组的浅表副本。

    int[] original = { 1, 2, 3 };
    int[] copy = (int[])original.Clone();

  2. CopyTo(Array array, int index)

    • 将当前数组中的元素复制到另一个数组中。

    int[] source = { 1, 2, 3 };
    int[] destination = new int[5];
    Array.Copy(source, destination, 3);

  3. Clear()

    • 将数组的所有元素设置为其类型的默认值。

    int[] array = { 1, 2, 3 };
    Array.Clear(array, 0, array.Length);

  4. Resize()

    • 改变数组的大小。这需要 System.Collections.Generic.List<T> 类,而不是 System.Array

    int[] array = { 1, 2, 3 };
    Array.Resize(ref array, 5); // 将数组大小改为 5

  5. Sort()

    • 对数组进行排序。

    int[] array = { 3, 1, 4, 2 };
    Array.Sort(array);

  6. BinarySearch()

    • 在已排序的数组中进行二进制搜索。

    int[] array = { 1, 2, 3, 4, 5 };
    int index = Array.BinarySearch(array, 3); // 返回 2

  7. IndexOf()

    • 返回数组中特定值的第一个匹配项的索引。

    int[] array = { 1, 2, 3, 4, 5 };
    int index = Array.IndexOf(array, 3); // 返回 2

  8. LastIndexOf()

    • 返回数组中特定值的最后一个匹配项的索引。

    int[] array = { 1, 2, 3, 4, 3 };
    int index = Array.LastIndexOf(array, 3); // 返回 4

  9. Reverse()

    • 反转数组中元素的顺序。

    int[] array = { 1, 2, 3, 4, 5 };
    Array.Reverse(array);

  10. Exists()

    • 检查数组中是否存在满足特定条件的元素。

    int[] array = { 1, 2, 3, 4, 5 };
    bool exists = Array.Exists(array, x => x > 3); // 返回 true

  11. Find()

    • 返回数组中满足特定条件的第一个元素。

    int[] array = { 1, 2, 3, 4, 5 };
    int found = Array.Find(array, x => x > 3); // 返回 4

  12. ForEach()

    • 对数组中的每个元素执行指定的操作。

    int[] array = { 1, 2, 3, 4, 5 };
    Array.ForEach(array, x => Console.WriteLine(x));

C#中的二维数组和交叉数组

在 C# 中,二维数组和交叉数组(Jagged Array)都是用于存储多个数组的数组,但它们在内存布局和性能方面有所不同。

二维数组

二维数组可以看作是数组的数组,其中的每个数组(称为子数组)都具有相同的长度,类似于数学中的矩阵。二维数组在内存中是连续存储的。

声明和初始化二维数组:

int[,] twoDArray = new int[5, 10]; // 5 行 10 列的二维数组
twoDArray[0, 0] = 1;
twoDArray[0, 1] = 2;
// ...
​
// 直接初始化
int[,] twoDArray = {
    { 1, 2, 3, 4, 5 },
    { 6, 7, 8, 9, 10 },
    // ...
};

交叉数组

交叉数组是数组的数组,其中的每个数组(称为子数组)可以具有不同的长度,因此它在内存中不是连续存储的。交叉数组在处理不同长度的子数组时更加灵活。

声明和初始化交叉数组:

int[][] jaggedArray = new int[5][]; // 5 个未初始化的子数组
jaggedArray[0] = new int[10];
jaggedArray[1] = new int[20];
// ...
​
// 直接初始化
int[][] jaggedArray = {
    new int[] { 1, 2, 3, 4, 5 },
    new int[] { 6, 7, 8, 9, 10, 11, 12 },
    // ...
};

性能考虑

  • 内存使用:二维数组在内存中是连续存储的,这可能在某些情况下导致内存浪费,尤其是当数组的某些行或列没有被完全使用时。交叉数组则可以根据需要为每个子数组分配确切的内存,从而节省内存。

  • 性能:二维数组由于在内存中连续存储,因此在访问时可能具有更好的性能,因为 CPU 缓存可以更有效地工作。交叉数组由于其非连续性,可能在访问时性能稍差。

选择使用

  • 如果所有子数组的长度都相同,并且对性能有较高要求,可以选择使用二维数组。

  • 如果子数组的长度不同,或者需要动态地调整子数组的大小,交叉数组是更好的选择。

## 在 C# 中,二维数组和交叉数组(Jagged Array)都是用于存储多个数组的数组,但它们在内存布局和性能方面有所不同。

二维数组

二维数组可以看作是数组的数组,其中的每个数组(称为子数组)都具有相同的长度,类似于数学中的矩阵。二维数组在内存中是连续存储的。

声明和初始化二维数组:

int[,] twoDArray = new int[5, 10]; // 5 行 10 列的二维数组
twoDArray[0, 0] = 1;
twoDArray[0, 1] = 2;
// ...
​
// 直接初始化
int[,] twoDArray = {
    { 1, 2, 3, 4, 5 },
    { 6, 7, 8, 9, 10 },
    // ...
};

交叉数组

交叉数组是数组的数组,其中的每个数组(称为子数组)可以具有不同的长度,因此它在内存中不是连续存储的。交叉数组在处理不同长度的子数组时更加灵活。

声明和初始化交叉数组:

int[][] jaggedArray = new int[5][]; // 5 个未初始化的子数组
jaggedArray[0] = new int[10];
jaggedArray[1] = new int[20];
// ...
​
// 直接初始化
int[][] jaggedArray = {
    new int[] { 1, 2, 3, 4, 5 },
    new int[] { 6, 7, 8, 9, 10, 11, 12 },
    // ...
};

性能考虑

  • 内存使用:二维数组在内存中是连续存储的,这可能在某些情况下导致内存浪费,尤其是当数组的某些行或列没有被完全使用时。交叉数组则可以根据需要为每个子数组分配确切的内存,从而节省内存。

  • 性能:二维数组由于在内存中连续存储,因此在访问时可能具有更好的性能,因为 CPU 缓存可以更有效地工作。交叉数组由于其非连续性,可能在访问时性能稍差。

选择使用

  • 如果所有子数组的长度都相同,并且对性能有较高要求,可以选择使用二维数组。

  • 如果子数组的长度不同,或者需要动态地调整子数组的大小,交叉数组是更好的选择。

数组和集合的区别

在 C# 中,数组和集合是两种不同的数据结构,它们在用途、功能和性能方面有显著的区别。以下是数组和集合的主要区别:

数组(Array)

  1. 固定大小:数组在声明时必须指定大小,一旦创建,其大小就固定不变。

  2. 类型安全:数组是强类型数据结构,即数组的每个元素都必须是相同的数据类型。

  3. 性能:数组通常在内存中连续存储,这使得数组访问速度快,但缺乏灵活性。

  4. 索引访问:数组通过索引访问元素,索引从 0 开始。

  5. 简单性数组结构简单,适用于存储同类型数据的简单集合。

  6. 内置支持:C# 提供了丰富的数组操作方法,如 Array.Sort()Array.Resize() 等。

集合(Collection)

  1. 动态大小:集合(如 List<T>Dictionary<TKey, TValue> 等)的大小是动态的,可以根据需要增长和缩小。

  2. 灵活性集合提供了更多的功能,如添加、删除、插入和搜索元素等。

  3. 泛型支持:集合通常支持泛型,这意味着你可以创建一个集合来存储任何类型的数据。

  4. 非连续存储:集合元素在内存中可能不是连续存储的,这使得它们在添加和删除元素时更加灵活,但可能影响性能。

  5. 丰富的数据结构:集合包括列表、队列、堆栈、字典等多种数据结构,每种结构都有其特定的用途和操作。

  6. LINQ 支持:集合与语言集成查询(LINQ)紧密集成,使得数据操作更加方便。

示例

  • 数组

    int[] numbers = new int[5]; // 创建一个大小为 5 的整型数组
    numbers[0] = 10;
    numbers[1] = 20;

  • 集合(例如 List<T>)

    List<int> numbers = new List<int>(); // 创建一个整型列表
    numbers.Add(10);
    numbers.Add(20);
    numbers.Add(30); // 可以动态添加元素

选择使用

  • 使用数组:当你需要存储固定数量的同类型数据,且对性能有较高要求时,可以选择数组。

  • 使用集合:当你需要一个灵活的数据结构,可以动态地添加、删除或搜索数据时,集合是更好的选择。

总结来说,数组和集合各有优势,选择使用哪一个取决于你的具体需求,包括数据的大小、类型、操作的复杂性以及性能要求。


http://www.kler.cn/a/301447.html

相关文章:

  • 父组件提交时让各自的子组件验证表格是否填写完整
  • 学了Arcgis的水文分析——捕捉倾泻点,河流提取与河网分级,3D图层转要素失败的解决方法,测量学综合实习网站存着
  • C语言导航 4.1语法基础
  • STL序列式容器之list
  • uniapp 跨域前端代理
  • Go 语言切片初始化与性能优化:使用 cap 参数的重要性
  • 基于SSM的二手交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档)
  • Java-手机号码检验
  • PyTorch:优化读取LMDB数据的五大策略
  • 828华为云征文 | 华为云Flexus X实例上实现Docker容器的实时监控与可视化分析
  • 实时监控电脑屏幕如何做到?怎么监视电脑屏幕?(30秒学会这3种简单又实用的方法)
  • rfc3550讲了什么?
  • MyBatis 一级缓存失效场景的深入分析
  • [java][tomcat]监控远程的tomcat
  • LeetCode之滑动窗口
  • jupyter里怎么设置代理下载模型
  • Qt使用绿色pdf阅读器打开文件
  • 菜鸟入门Docker
  • Python的安装与配置并在本地盘符创建共享路径打造低成本私人云盘
  • 【Unity】il2cpp 项目Build报错
  • 白月光git
  • 怎么样处理浮毛快捷又高效?霍尼韦尔、希喂、米家宠物空气净化器实测对比
  • C# WPF编程-串口通信
  • 培训第九周(部署k8s基础环境)
  • 【STL中容器汇总】map、list、vector等详解
  • C#中的字段和属性