[C#.NET 拾遺補漏]02:數組的幾個小知識

閱讀本文大概需要 1.5 分鐘。

數組本身相對來說比較簡單,能想到的可寫的東西不多。但還是有一些知識點值得總結和知曉一  下。有的知識點,知不知道不重要,工作中用的時候搜索一下就可以了,畢竟實現一個功能代碼的寫法有很多種,再牛的人也不可能完全熟悉一門語言的每個細節。當然了,偶然地知道了一些小知識或小技巧也是一種小小的收穫。在你看這篇小文時,或許這種偶然的事情就正在發生。我們先從數組的初始化開始吧。

數組的定義和初始化

定義和初始化一個數組有好幾種方式,隨着 C# 版本升級,方式也越來越簡單:

int[] arr = new int[3];           // 定義一個長度為 3 的數組
int[] arr = new int[3] {1, 2, 3}; // 定義一個長度為 3 的數組並初始化
int[] arr = new [] {1, 2, 3}; // 上面的簡寫
int[] arr = {1, 2, 3}; // 上面的進一步簡寫

我們知道當定義一個固定長度的數組沒有初始化時,比如:

int[] arr = new int[3];

雖然沒有初始化,但它是有默認值的,這個數組中包含了 3 個值為 0 的整數。如何使用非默認值創建一個數組呢?可以使用 System.Linq 命名空間下的 Enumerable.Repeat 方法:

// 創建長度為 5 的整形數組,並用 100 來填充
int[] arr = Enumerable.Repeat(100, 5).ToArray();

// 創建長度為 5 的字符串數組,並用“C#”來填充
string[] arr = Enumerable.Repeat("C#", 5).ToArray();

數組的複製、克隆與比較

把一個數組的元素複製到另一個數組,可以使用 Array.Copy() 方法,複製時源數組取值和目標數組賦值都是從索引 0 開始的:

var sourceArray = new int[] { 11, 12, 3, 5, 2, 9};
var destinationArray = new int[3];
Array.Copy(sourceArray, destinationArray, 3);
// destinationArray = [11, 12, 3]

克隆一個數組很簡單:

var sourceArray = new int[] { 11, 12, 3 };
var destinationArray = (int[])sourceArray.Clone();
// destinationArray = [11, 12, 3]

比較兩個數組是否一樣,即兩個數組包含的元素及元素的順序是否都一樣,可以使用數組的 SequenceEqual 方法:

int[] arr1 = { 3, 5, 7 };
int[] arr2 = { 3, 5, 7 };
bool result = arr1.SequenceEqual(arr2); // true

以上只是羅列幾個有代表性的比較快捷簡單的數組操作,在 C# 中藉助 Linq 可以實現更複雜的數組操作,這裏先不作總結。

使用指針遍曆數組

實際的 C#開發中很少會直接用到指針,在需要進行底層操作時可能會用到。在 C# 中使用指針時需要在 unsafe 上下文中操作:

int[] arr = new int[] {1, 6, 3, 3, 9};

// 使用 foreach
foreach (int element in arr)
{
Console.WriteLine(element);
}

// 使用指針
unsafe
{
int length = arr.Length;
fixed (int* p = arr)
{
int* pInt = p;
while (length-- > 0)
{
Console.WriteLine(*pInt);
pInt++; // 將指針移到下一個元素
}
}
}
// 依次輸出:1 6 3 3 9

這裏只是讓大家知道有這麼一回事,指針不是本篇的話題,更多關於指針的操作可以訪問:

https://bit.ly/2MmIsNl

生成有序數組

我就見過有人使用 for 循環生成一個從 n 到 m 的有序數組,其實 C# 提供了 Enumerable.Range 方法可以很容易地創建一個有序的整型數組。示例:

// 創建数字從 1 到 100 的數組
int[] sequence = Enumerable.Range(1, 100).ToArray();

// 結合 Linq 還可以實現更複雜的數組創建邏輯
int[] squares = Enumerable.Range(2, 10).Select(x => x * x).ToArray(); // 4, 9, 16...

多維數組和交錯數組的區別

簡單來說,多維數組每一行長度都是固定的,比如二維數組是一個 m 行 n 列的矩陣:

int[,] arr = {
{1, 2, 3, 4},
{4, 2, 1, 3},
{2, 1, 3, 4},
}

而交錯數組(又叫鋸齒數組)的每一行可以有不同的大小,表示的是數組的數組。比如:

int[][] arr = {
new [] {1, 2, 3, 4},
new [] {1, 2},
new [] {1, 2, 3},
}

它們的定義、初始化、取值、賦值等都有明顯的區別。

先看多維數組:

// 多維數組的定義
int[,] arr = new int[10, 10]; // 二維數組
int[,,] arr = new int[10, 10, 10]; // 三維數組

// 多維數組的初始化 (new int[3, 2] 可以省略)
int[,] arr = new int[3, 2] { {1, 1}, {2, 2}, {3, 3} };

// 多維數組的取值
Console.WriteLine(arr[2, 1]); // 3

// 多維數組的賦值
arr[2, 1] = 10;

再對比交錯數組:

// 交錯數組的定義
int[][] arr = new int[10][]; // 二層:數組的數組
int[][][] arr = new int[10][][]; // 三層:數組的數組的數組

// 交錯數組的初始化 (new int[3][] 可以省略)
int[][] arr = new int[3][] { new [] {1}, new [] {2, 2}, new [] {3, 3, 3} };

// 交錯數組的取值
Console.WriteLine(arr[2][1]); // 3

// 多維數組的賦值
arr[2][1] = 10;

注意:多維數組每行長度必須一致;交錯數組第二個 [] 是不能有数字的。兩者的 Length 屬性意義也是不一樣的,多維數組的 Length 屬性取的是數組所有元素的總數,而交錯數組取的是第一層的數組的個數。例如:

int[,] arr1 = new int[3, 2] { { 1, 1 }, { 2, 2 }, { 3, 3 } };
Console.WriteLine(arr1.Length); // 輸出:6

int[][] arr2 = new int[3][] { new[] { 1 }, new[] { 2, 2 }, new[] { 3, 3, 3 } };
Console.WriteLine(arr2.Length); // 輸出:3

建議:除了某些像矩陣這樣的操作場景可能更適合使用多維數組,大多數場景應盡量選擇使用交錯數組。功能上多維數組可以實現的,交錯數組也都能實現,反過來不一定可以。另外,根據 stackoverflow 網友的回答(下面參考鏈接),在 .NET 中,交錯數組性能上要好於多維數組。

參考:https://bit.ly/2Mqn6P1

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

網頁設計最專業,超強功能平台可客製化

※別再煩惱如何寫文案,掌握八大原則!