iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0

嗨嗨壓~今天繼續特訓
應該差不多快要結束了吧...大概吧(?
今天來說陣列,也是一個很基本的技能

1. 陣列(Array)

陣列(Array)是由多個相同資料型別的變數在記憶體中前後連續串在一起。程式中使用陣列時機是在需要處理多個同性質資料的時候,以陣列中的陣列元素來取代同性質的變數,即將每個陣列元素視為一個變數。陣列元素是由陣列名稱其後跟著中括號括住陣列的註標值或稱索引值組成,表示該陣列元素在此陣列中是第幾個資料,陣列的索引值是從0開始計算第幾個資料,比如 a[0]是a陣列的第一筆、a[1]是第二筆,以此類推。
那我們要怎麼創建陣列呢?非常簡單,如下

1.宣告陣列語法:
    資料型別[] 陣列名稱;
2.創建陣列語法:
    陣列名稱 = new 資料型別[陣列大小];

當然也可以一行解決

資料型別[] 陣列名稱 = new 資料型別[陣列大小];

上面宣告陣列在名稱後面只跟著一個註標屬於一維陣列。若跟著兩個註標屬於二維陣列,以此類推。C#最多允許使用32維陣列。每一維的註標是由0開始算起,維度間用逗號隔開。
陣列在使用之前必須宣告,給予該陣列名稱、資料型態、陣列大小,接下來使用new關鍵字建立陣列的物件實體。C#陣列語法如下:

1.一維陣列: 資料型態[] 陣列名稱 = new 資料型態[陣列大小];
2.二維陣列: 資料型態[,] 陣列名稱 = new 資料型態[第一維陣列大小,第二維陣列大小];

陣列經過宣告和建立該物件的實體後,需給予陣列元素初值,才能存取陣列。由於陣列元素相當於個變素,因此可用=指定運算子直接指定每個陣列元素的值,如:

int[] score = new int[4];
score[0] = 40; score[1] = 50; score[2] = 60; score[3] = 70;

當然也可以合併在一起

// 資料型態[]陣列名稱=new 資料型態[]{陣列初值串列};
int[] a = new int[]{1, 2, 3, 4, 5};

再來是陣列裡面常用的屬性和方法
在System.Array類別中提供了建立、管理、搜尋和排序陣列的屬性和方法。假設建立下列a1一維陣列與a2二維陣列來說明下表陣列屬性與方法的使用

int[] a1 = new int[3];
int[,] a2 = new int[3,4];
陣列物件的成員 功能
Length屬性 取得指定陣列內的所有陣列元素的總數,傳回值為整數。例如: (1)a1.Length =>傳回3 (2)a2.Length => 傳回12
Rank屬性 取得指定陣列維度的數目,傳回值整數。例如: (1)a1.Rank =>傳回1 (2)a2.Rank => 傳回2
IsReadOnly屬性 傳回指定陣列是否為唯獨,傳回值為布林值。例如: a1.IsReadOnly => 傳回false
GetUpperBound屬性 取得指定陣列中某一維度上限,傳回值維整數。例如: (1) a1.GetUpperBound(0) => 取a1第1維上限,傳回2 (2) a2.GetUpperBound(1) => 取a2第1維上限,傳回3
GetLowerBound屬性 取得指定陣列中某一維度下限,傳回值維整數。陣列維度的下限是由0開始
GetLength屬性 取得指定陣列中某一維度的陣列元素總數,傳回值維整數。例如: (1) a1.GetLength(0) => 取a1第1維陣列元素總數,傳回3 (2) a2.GetLength(1) => 取a2第1維陣列元素總數,傳回4
CreateInstance屬性 建立指定陣列資料型態和大小的一維陣列(具有以零起始的索引)。 (1) 產生一個含有五個陣列元素的a1整數陣列 Array a1 = Array.CreateInstance(typeof(Int32),5); (2) 產生一個名稱為a2的2*3字串二維陣列 Array a2 = Array.CreateInstance(typeof(String),2,3);
SetValue屬性 設定一維、二維...陣列中陣列元素的值。 (1)設定一維陣列第3個陣列元素的值為10 a1.SetValue(10,2); (1)設定二維陣列第1列第2欄陣列元素的值為10 a2.SetValue(10,0,1);
GetValue屬性 取得一維、二維...陣列中位於指定位置的值。 (1)取得一維陣列第3個陣列元素的值 a1.GetValue(2); (1)取得二維陣列第1列第2欄陣列元素的值 a2.GetValue(0,1);

2. foreach

foreach敘述和for敘述的功能一樣,兩者的差異在foreach不用給予迴圈正確的初值、條件和終值,他會如下面語法自動將指定集合物件(如陣列)中的元素逐一指定給變數,帶入回圈內處理,一直到所有元素都處理完畢才離開迴圈,繼續執行接在foreach後面的敘述。語法如下:

foreach(資料型態 變數 in 集合物件)
{
    //敘述區域
}
int[] tail = new int[]{10,20,30,40,50};
int sum = 0;
foreach(int height in tail)
{
    sum += height;
}

再來是陣列的排序和搜尋
當要對陣列中的陣列元素做遞增遞減排序時,一般都是使用雙層for來執行,對初學者而言是大工程。還好 .NET Framework類別資料庫提供System.Array類別的靜態方法來解決這問題,只要一行程式就可以輕鬆完成陣列的排序、反轉、搜尋和清除資料的工作。下表是Array類別中常用的靜態方法:

Array類別靜態方法 功能
BinarySearch [語法] int n = Array.BinarySearch(陣列名稱,欲搜尋資料); [說明] 透過二分搜尋法搜尋資料是否存放在陣列中,使用此方法前必須事先使用Array.Sort()方法將陣列做遞增排序才可使用,適用於搜尋資料量較大的陣列,若找到資料傳回該陣列元素的索引值,若沒有傳回-1
Clear [語法] Array.Clear(陣列名稱,起始註標,刪除個數); [說明] 將陣列中指定範圍內陣列元素內的內容清除
IndexOf [語法] int n = Array.IndexOf(陣列名稱,欲搜尋資料); [說明] 搜尋資料是否存放在陣列中。若有找到資料會傳回該陣列元素索引值,若沒有找到資料則傳回-1
Sort方法 [語法1] Array.Sort(陣列名稱); [說明1] 對指定的一維陣列物件遞增排序 [語法2] Array.Sort(陣列名稱1,陣列名稱2); [說明2] 依據第一個引數陣列的索引值遞增來排序,第二引數陣列的對應索引值亦跟著移動 [語法3] Array.Sort(陣列名稱,起始註標,排序長度); [說明3] 將指定一維陣列由指定起始陣列註標開始取指定長度的陣列元素進行遞增排序
Reverse方法 [語法1] Array.Reverse(陣列名稱); [語法2] Array.Reverse陣列名稱,起始註標,排序長度); [說明] 將指定一維陣列整個或由指定註標後面多少個陣列元素進行反轉。若想遞減排序,可以先執行Array.Sort()進行遞增後再執行Array.Reverse()反轉陣列,則該陣列就會變成遞減
GetEnumerator方法 傳回Array的IEnumerator

3. 規則陣列和不規則陣列

宣告多維陣列時,其維度是否相同分為下面兩種:規則陣列不規則陣列
阿規則陣列又稱矩陣陣列,是屬於二維陣列,規則陣列是指每列的陣列元素都相同。
之前已經介紹過用法了,所以就不多說了
那我們來說說不規則陣列
C#提供一個建立特殊的二維陣列,陣列中的每一列長度可以不相同,稱為不規則陣列(Jagged Array)或稱非矩陣陣列。所謂的不規則陣列就是陣列中還可以存放陣列,每一列的長度不同,可以用來建立每列不同長度的表格。至於之前說的規則陣列,因為長度一致,所以可以用來建立一般表格。不規則陣列的語法如下:

資料型態[][] 陣列名稱 = new 資料型態[陣列大小][];

建立不規則陣列如下:

//先宣告一個不規則陣列。如宣告一個名為a的不規則陣列,此不規則陣列有3列
int[][] a = new int[3][];
//接著分別設定不規則陣列每列陣列的大小,如將第0、1、2列分別配置3、4、5個陣列元素
a[0] = new int[3];
a[1] = new int[4];
a[2] = new int[5];

經過上面宣告所建立的不規則陣列如下:

不規則陣列

4. 結構與結構陣列

陣列內的資料是一群同性質且資料型態相同資料的集合,程式中同時要處理多個不同性質的資料,就需要多個陣列來處理,不但使程式長還難維護,所幸C#提供另外一種 使用者自定型別(User Defined Type) 稱為 結構(Structure) 或稱 紀錄(Record) ,它允許將不同資料型態的資料放在一起構成一筆紀錄,多筆資料時也不用像陣列必須分成多個陣列來存放資料。
要怎麼使用結構呢?那就讓我們來說說結構變數。
結構是由一些邏輯相關的資料欄或稱欄位(Field)所構成。結構必須給予結構名稱,且每一個欄位也要給予一個欄位名稱和必須要定義,然後再給予宣告和初值才能使用。

//定義結構
struct 結構名稱{
    資料型態1    欄位名稱1;
    資料型態2    欄位名稱2;
    資料型態3    欄位名稱3;
}
//宣告結構變數
struct 結構名稱 結構變數;
//設定結構變數初值
結構名稱.欄位名稱 = 設定值;

這就是結構的用法,很簡單對吧!
在來是結構陣列,上面的用法只能儲存一筆資料,代表一個結構變數只能代表一筆資料,若有很多筆資料就需要使用到結構陣列。
如定義結構名稱為student的結構陣列,每筆紀錄是由座號(NO)、姓名(Name)、成績(score)三個不同資料型態的欄位構成一筆紀錄,來儲存5個學生的成績資料,該紀錄如下表:

座號欄位 姓名欄位 成績欄位
1 Tom 75
2 Paul 80
3 Jack 90
4 Mary 100
5 Jane 65

程式如下:

//定義student結構
struct student{
    public int NO;
    public string Name;
    public int score;
}
//宣告a為具有student結構的結構陣列,大小為5
student[] a = new student[5];
//設定結構變數的初值
a[0].NO = 1; a[0].Name = "Tom"; a[0].score = 75;
a[1].NO = 2; a[1].Name = "Paul"; a[0].score = 80;
a[2].NO = 3; a[2].Name = "Jack"; a[0].score = 90;
a[3].NO = 4; a[3].Name = "Mary"; a[0].score = 100;
a[4].NO = 5; a[4].Name = "Jane"; a[0].score = 65; 

當然也可以將上面宣告跟設定初值合併成下面敘述:

student[] a = new student[]{
    new student(){NO = 1, Name = "Tom", score = 75},
    new student(){NO = 2, Name = "Paul", score = 80},
    new student(){NO = 3, Name = "Jack", score = 90},
    new student(){NO = 4, Name = "Mary", score = 100},
    new student(){NO = 5, Name = "Jane", score = 65},
};

好啦~特訓就到這邊結束吧!
其實還有一堆要說的,但我怕再說下去就要被說成在水文章了##
而且我也怕我後面的東西寫不完
那就把之前的攻略丟下面吧~
https://ithelp.ithome.com.tw/users/20150241/ironman/5141

tags: 2023鐵人賽

上一篇
2023鐵人賽 Day 04 C#深入行前訓練-3
下一篇
2023鐵人賽 Day 06 C#的另一條副本之路-Windows Form
系列文
C#世界深入探險,走走不同副本之路-Windows Form30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言