本次課我們要學習數組的屬性、foreach的用法、我上節課提到的交錯數組,我會通過多個例子的示範講解讓你們理解交錯數組定義已經與規則的二維數組(矩形數組)的區別加深理解,下一節我們還將學習數組的常用方法。
下面我們來學習一下數組的屬性,什麼是屬性呢?在以後學習類的時候我會給大家詳細的講解,現在我給你們舉個現實生活的例子,協助你們理解什麼叫屬性,屬性一般都是名詞,表示它的所有者(即對象)擁有的特性,如抹布(對象)的顏色、大小(屬性),而下一節將學習的數組的方法一般是動詞,如抹布的功能,抹布(對象)清除(方法)案頭、車輛、地面(這些動作的賓語也可以比喻成以後要學習的參數),現在你們就記住屬性是描述對象的特性的,一般是名詞,方法是描述對象功能的,一般是動詞。那數組有哪些屬性呢?
數組的屬性:Array.Length數組的容量
利用這個屬性,我們可以取得數組對象允許儲存的容量值,也就是數組的長度、元素個數,這個比較好理解,數組還有其他的屬性,比如數組的維數等,屬性的用法比較簡單,學會一種,其他的格式基本一致,這裡我們就不舉例了。
在上一節最後一個例子時我們用到了通過索引(index)得到數組元素的值Array[index],但是當數組的維數、容量較多時,採用索引這種方法就會繁雜,不僅代碼量大也會降低編程效率,針對這個問題C#提供了foreach語句,專門用來讀取集合/數組中的所有元素,我們把這種功能叫做遍曆。文法書寫如下:
遍曆數組:foreach(type objName in collection/Array)
這段語句會逐一檢查數組中的所儲存的變數值,並且一一將其取出,其中的type是你所要讀取的數組對象將要儲存在objName變數的資料類型,而objName是定義了一個type類型的變數名,代表每一次從集合和數組(collection/Array)中取得的元素,collection/Array則是所要存取的數組對象。用這種方法只需寫一個foreach就可以遍曆出除交錯數組以外的所有維數的數組。
註: objName的資料類型type必須與collection/Array對象的類型相同或比它大。
下面我們舉一個用foreach和for遍曆規則數組的例子,其中涉及到了一個數組得到維數的方法,比較foreach在一次性遍曆規則數組上的優勢。
int[,,] a = new int[2, 2, 2] { {{ 1, 2 }, { 3,4}},{{ 5, 6 }, { 7,8}} };//定義一個2行2列2縱深的3維數組a
for (int i = 0; i < a.GetLength (0) ;i++ ) //用Array.GetLength(n)得到數組[0,1,,,n]上的維數的元素數,0代表縱,1行,n代表此數組是n+1維
{
for (int j = 0; j < a.GetLength(1); j++)
{
for (int z = 0; z < a.GetLength(2);z++ )//如果數組有n維就得寫n個for迴圈
{
Console.WriteLine(a[i,j,z]);
}
}
}
用foreach迴圈一次性遍曆a數組
int[,,] a = new int[2, 2, 2] { {{ 1, 2 }, { 3,4}},{{ 5, 6 }, { 7,8}} };//定義一個2行2列2縱深的3維數組a
foreach(int i in a)
{
Console .WriteLine (i);
}
這兩種代碼執行的結果是一樣的都是 每行一個元素,共8行,元素分別是1 2 3 4 5 6 7 8
下面我們再做個例子,是一個利用for和foreach迴圈做的存取數組元素的例子,首先提示使用者輸入學生的個數,然後把學生個數作為儲存學生姓名的數組names的元素個數,採用for迴圈按照數組的索引i從0位開始迴圈輸出“輸入學生姓名”的提示,並把使用者輸入的學生姓名按照其在數組的索引方式names[i]儲存在names數組中,for迴圈次數的最大值(即索引的最大值)通過數組屬性.Length得到,上節課我們說過容量與索引之間的關係是index=Array.Length-1,本題即i的最大值<names.Length,儲存後,提示“輸出學生姓名”,再用foreach迴圈一次性遍曆names數組中儲存的每個元素(學生的姓名),一個一個的把它賦值給name元素,然後輸出到控制台上。
通過這個例子,我們複習了在c語言中就學到的for迴圈,用索引方式儲存數組元素的值,以及今天學習的.length屬性、foreach遍曆的用法,必須注意的是,藉助foreach,只能一一取得數組中的元素,並不能利用這種語句改變數組所儲存的元素。做個foreach和for的使用是你必須熟練掌握的編程技能,同學們要引起重視。
下面我們來學習交錯數組,也稱鋸齒形數組,是一種不規則的二維數組,它與矩形數組(二維數組)最大的差異,在於數組中每一行的長度並不相同,我們可以把它想象成有不同長度的一維數組組合而成的二維數組,所以交錯數組也被稱為“數組中的數組”,它比規格的矩形數組節省了記憶體空間,當同時也要在建立和使用時按照其特點進行操作。建立交錯數組所使用的文法不同於前面的矩形數組,必須使用兩個[]運算子,第一個代表[n]代表行數。看下面的圖片,用圖片的執行個體為大家講解交錯數組的聲明。
交錯數組聲明:行是固定的
第一步:int[][] jaggedArray = new int[4][];
如果採用分布聲明數組元素方式,元素的個數必須書寫,因為交錯數組的行是固定的,而每行的列是不固定的,所以在初始化時必須在第一個[]中寫明行數4.
第二步:交錯數組每行初始化
jaggedArray[0] = new int[6];
jaggedArray[1] = new int[2];
jaggedArray[2] = new int[3];
jaggedArray[3] = new int[5];
給每行看出一個一維數組,再定義列數,然後再給你可以採用索引賦值法,給單個元素賦值。如:
第三步:採用索引賦值法,給單個元素賦值
jaggedArray[2][0] = 5;
jaggedArray[3][4] = 32;
或者你可以將上面的二、三步合并為一步,為每一行都賦值。
第二步:直接給交錯數組初始化賦值
jaggedArray[0] = new int[] { 1, 3, 5, 7, 9,13 };
jaggedArray[1] = new int[] { 0, 2, };
jaggedArray[2] = new int[] { 5,11, 22 };
jaggedArray[3] = new int[] { 3,5,7,10, 32 };
我們還可以在聲明數組時將其初始化,如:
int[][] jaggedArray = new int[][]
{
new int[] {1,3,5,7,9},
new int[] {0,2},
new int[] {5,11, 22 },
new int[] {3,5,7,10, 32}
};
下面我們來做一個給交錯數組賦值以及遍曆交錯數組的例子,讓我們體會一下和規則數組的代碼區別。我來解釋一下下面的例子,我定義了3行的交錯數組,第一行輸出姓名、口頭禪、籍貫,第二行用直接賦值法定義了3列分別是劉大夫、很是費解、迪斯尼,第三行只定義了2列,按照索引方式給3行1列的元素賦值為蠟筆小新、用索引的方式說賦的下一個值為給行索引為2列索引為1的元素賦值為老婆!
string[][] xinxi = new string[3][];
Console.WriteLine("正在給交錯數組賦值!");
xinxi[0] =new string [] {"姓 名","口頭禪","籍 貫"};
xinxi[1] = new string[] { "劉大夫", "很是費勁","《一日一囧》" };
xinxi[2] = new string[2];
xinxi[2][0] = "蠟筆小新";
xinxi[2][1] = "老婆!";
Console.WriteLine("現在準備輸出!");
Console.WriteLine("*************");
foreach(string [] hang in xinxi )//因為交錯數組的特性必須先用數組hang儲存遍曆出交錯數組xinxi的每一行
{
foreach (string lie in hang)//在行的數組中遍曆每一列儲存在lie元素中
{
Console.Write(lie);//輸出遍曆的元素
}
Console.WriteLine();
}
結果顯示為:
我們把上面的例子修改一下用for迴圈輸出元素,讓我們體會一下交錯數組和規則數組的區別。
交錯數組:string[][] xinxi = new string[3][];
Console.WriteLine("正在給交錯數組賦值!");
xinxi[0] = new string[] { " 姓 名 ", " 口頭禪 ", " 籍 貫 " };
xinxi[1] = new string[] { " 劉 大 夫 ", " 很是費勁" , " 《一日一囧》" };
xinxi[2] = new string[2];
xinxi[2][0] = " 蠟筆小新 ";
xinxi[2][1] = " 老婆!";
Console.WriteLine("現在準備輸出!");
Console.WriteLine("******************************");
for (int i = 0; i < xinxi.Length;i++ )//先得到行索引
{
for (int j = 0; j < xinxi[i].Length; j++)//得到行中的列索引
{
if (xinxi[i][j] != null) //如果此元素不為空白時輸出元素值
{
Console.Write(xinxi[i][j]);
}
else
{
Console.Write("-------"); //如果此元素為空白時輸出“-------”
}
}
Console.WriteLine();
}
輸出結果和上一張圖片結果一致。而如果把第三行的列元素定義為3時,此數組變成了規則的3行3列的二維數組,還是賦索引為0和1的元素值時:
二維數組:
string[][] xinxi = new string[3][];
Console.WriteLine("正在給二維數組賦值!");
xinxi[0] = new string[] { " 姓 名 ", " 口頭禪 ", " 籍 貫 " };
xinxi[1] = new string[] { " 劉 大 夫 ", " 很是費勁" , " 《一日一囧》" };
xinxi[2] = new string[3];
xinxi[2][0] = " 蠟筆小新 ";
xinxi[2][1] = " 老婆!";
Console.WriteLine("現在準備輸出!");
Console.WriteLine("******************************");
for (int i = 0; i < xinxi.Length;i++ )//先得到行索引
{
for (int j = 0; j < xinxi[i].Length; j++)//得到行中的列索引
{
if (xinxi[i][j] != null) //如果此元素不為空白時輸出元素值
{
Console.Write(xinxi[i][j]);
}
else
{
Console.Write("-------"); //如果此元素為空白時輸出“-------”
}
}
Console.WriteLine();
}
結果如片:
提問:區別下兩張圖片發現了什嗎?二維數組的第3行第3列我們沒有賦值,但是會出現————,說明它在建立的時候給這個位置的元素佔位了,只是根據上節課說的原則按照資料類型給了一個預設的null值,當我們用“------”取代時,能夠顯示出來,而交錯數組,沒有建立元素的位置時,它是不存在的。
本節我們主要是學習foreach在兩種數組中的遍曆,下一節我們來學習數組的常用方法。