C#&&數組

來源:互聯網
上載者:User

標籤:

數組是最常用的資料結構,幾乎在所有的程式設計語言中都會出現。在C#裡用數組的話需要建立一個System.Array類型的對象,它是所有數組的抽象基類。
Array類提供了一組排序和尋找的方法
另一個可以建立數組的替代品是ArrayList,ArrayList是可以按需要動態增長的數組。
在不能確定一個數組的大小的情況下,或在程式的生命週期內數組的大下需要改變時,ArrayList是個好的選擇。
還有包括拷貝,複製的內容,比較是否相等以及用Array和ArrayList的靜態方法。

 

聲明和初使化數組
數組聲明時用下面的格式:

 

type[] array_name;
type就是資料類型,比如
string[] names;

 

第二行需要執行個體化這個數組(因為是System.Array類型)並指定數組的大小。代碼如下:
names = new string[10];
這樣就為10個字串分配了記憶體。

也可以兩句合在一起寫:

string[] names = new string[10];
有時候你想把聲明,執行個體化,指定資料三個步驟同時進行,那就這樣子:
int[] numbers = new int[] {1,2,3,4,5};
這一串數字,叫做初使化列表,用花括弧括起來,每個元素用逗號隔開。
當用這種方式聲明數組時,不用指定數組大小,編譯器會自動根據初使化列表的個數來指定。

設定和存取數組元素
數組元素的儲存既可以直接儲存,也可以調用SetValue方法,直接儲存方法需要用索引指定數組內的位置,向下面這樣:

Names[2] = "Raymond";
Sales[19] = 23123;
SetValue方法提供了一個更物件導向的做法去設定數組元素的值,此方法有兩個參數,一個是索引數,另一個是值。
names.SetValue[2, "Raymond"];
sales.SetValue[19, 23123];
數組元素的取出既可以直接取得,也可以調用GetValue方法,GetValue用一個簡單的參數:索引數

myName = names[2];
monthSales = sales.GetValue[19];

通過迴圈去取得數組內的每個元素是很常見的。程式員寫迴圈時會經常犯一個錯誤:就是寫死了迴圈的上限或調用取得上限的方法。
錯誤主要是因為數組的上限是動態
for (int i = 0; i <= sales.GetUpperBound(0); i++)
totalSales = totalSales + sales[i];
檢索數組中繼資料的方法和屬性:
Length:返回數組元素的所有個數。
GetLength:返回數組元素一維內的個數。
Rank:返回維數
GetType:返回當前數組執行個體的類型

 

Length方法在統計多維陣列內元素的個數時很有用。要不然就用GetUpperBound方法+1取這個值
因為Length方法返回的是數組內所有元素的個數,GetLength方法返回的是一維內數組的個數。
Rank屬性可以在運行時改變數組的大小而不用擔心遺失資料,這個在章節後面詳細討論。
GetType方法是當你確定不了數群組類型時用來判定資料類型的方法,比如數組是入參。
下面的代碼,會建立一個Type類型的變數,允許我們調用一個類方法:IsArray()來判定這個對象是否是數組,
如果是數組的話,那麼就返回數組的資料類型
int[] numbers;
numbers = new int[] {0,1,2,3,4};
Type arrayType = numbers.GetType();
if (arrayType.IsArray)
Console.WriteLine("The array type is: {0}", arrayType);
else
Console.WriteLine("Not an array");
Console.Read();

GetType方法不僅返回數組的類型,也告訴我們數組其實是一個對象,下面是輸出的代碼:
The array type is: System.Int32[]
方括弧說明這個對象是個數組,也注意一下當顯示數群組類型時我們使用的格式。
知道了這個,我們不能轉換把這個類型轉換成string去串連剩下的字串

多維陣列
目前我們的討論都限於一維數組,C#裡,可以用最多32維的數組,雖然3維以上的數組就不常用了(還混亂的很)。
多維陣列是用指定了每維上限的數組聲明的,2維的聲明:
int[,] grades = new int[4,5];
聲明一個4行5列的數組,2維數組一般用來類比矩陣。
你也可以聲明一個不指定每一維的上限的多維陣列,用逗號分開就行了。
舉個例子:
double[,] Sales;
聲明一個2維數組,
double[,,] sales;
聲明一個3維數組,當你聲明數組不指定某維的上限時,用的時候要指定

 

多維陣列也可以用初使化列表,看下面的代碼:
Int[,] grades = new int[,] {{1, 82, 74, 89, 100},
{2, 93, 96, 85, 86},
{3, 83, 72, 95, 89},
{4, 91, 98, 79, 88}}
首先,注意數組的上限是沒有指定的,當用初使化列表來初使化一個數組時,
不能指定該數組的上限。編譯器會通過初使化列表計算每一維的上限。
初使化列表本身是一對花括弧,每一行,每一個元素都用逗號分開。

取得多數組的元素和一維是差不多的,傳統技術是這樣的:

grade = Grades[2,2];
Grades[2,2] = 99
或者也可以用GetValue方法
grade = Grades.GetValue[0,2];

但不能用SetValue方法來設定多維陣列的資料,因為這個方法只有兩個參數。

在多維陣列裡計算所有元素是很常見的操作,雖然常常時是基於某一行或某一列的資料。
用Grades這個數組,如果數組的每一行是一條學生記錄,我們可以計算年級裡每個學生的平均分:

 

(代碼如下)

int[,] grades = new int[,] {{1, 82, 74, 89, 100},
              {2, 93, 96, 85, 86},
              {3, 83, 72, 95, 89},
              {4, 91, 98, 79, 88}};
int last_grade = grades.GetUpperBound(1);
double average = 0.0;
int total;
int last_student = grades.GetUpperBound(0);
for(int row = 0; row <= last_student; row++) {
    total = 0;
for (int col = 0; col <= last_grade; col++)
      total += grades[row, col];
average = total / last_grade;
Console.WriteLine("Average: " + average);
  }
}

 

參數數組
很多方法的定義需要提供好幾個參數,但是有時候你想寫一個參數個數可選的方法。
你可以聲明一個參數數組。參數數組是用關鍵字ParamArray定義參數列表的。
下面這個方法允許任意個數的參數,傳回值是參數的個數。static int sumNums(params int[] nums) {
int sum = 0;
for(int i = 0; i <= nums.GetUpperBound(0); i++)
sum += nums[i];
return sum;
}

 

這個方法可以被以下代碼調用:

total = sumNums(1, 2, 3);
total = sumNums(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
當你用參數數組定義一個方法時,參數數組必須放在此方法所有參數的最後,
這樣編譯器可以正確處理參數,否則,編譯器不知道參數個數什麼時候結束。

不規則數組
當你建立一個多維陣列時,你一直建立的是每一行的元素個數相同的結構。打個比方,你看下面的代碼:

int sales[,] = new int[12,30];//銷售人員每個月每天的情況
假設每行(每月)有同樣的元素個數(天數),而實際上有的月31天,有的30天,有的29.
這樣資料就有空位置,在這個數組裡問題倒不大,但是一旦資料量大了以後就很浪費了

解決問題的方法是使用一個不規則數組來代替二維數組。
不規則數組是一個數組的每一行也是數組的數組。不規則數組的每一維是一維數組,叫它“不規則”是因為每一行的個數不同。
不規則數組的樣子可能不是一個矩形,但是有不規則的邊。
不規則數組用數組名後的兩對括弧聲明。第一對括弧指定行數,第二對是留空的。
int[][] jagged = new int[12][];

這句代碼看上去有點怪,但是分開來理解就明白了。這個不規則數組有12個元素。
每個元素也是一個數組。初使化列表其實就是為了初使化每一行資料,說明每一行元素是有12個元素的資料,每個元素都初使成預設值。
一旦不規則數組聲明,每一行的元素就可以指定指了,下面的代碼就是設定值的:
jagged[0][0] = 23;
jagged[0][1] = 13;
. . .
jagged[7][5] = 45;
第一對括弧指明行號,第二對括弧指明這一行的某一個元素。
第一句取第一行的第一個元素,第二句取第一行的第二個元素。
第三句取第6行的第8個元素。

一個用不規則數組的例子,下面的程式建立一個叫做sales的數組,迴圈用來計算這兩個月每周的平均銷售情況。

using System;
class class1 {
static void Main[] {
int[] Jan = new int[31];
int[] Feb = new int[29];
int[][] sales = new int{Jan, Feb};
int month, day, total;
double average = 0.0;
sales[0][0] = 41;
sales[0][1] = 30;
sales[0][0] = 41;
sales[0][1] = 30;
sales[0][2] = 23;
sales[0][3] = 34;
sales[0][4] = 28;
sales[0][5] = 35;
sales[0][6] = 45;
sales[1][0] = 35;
sales[1][1] = 37;
sales[1][2] = 32;
sales[1][3] = 26;
sales[1][4] = 45;
sales[1][5] = 38;
sales[1][6] = 42;
for(month = 0; month <= 1; month++) {
total = 0;
for(day = 0; day <= 6; day++)
total += sales[month][day];
average = total / 7;
Console.WriteLine("Average sales for month: " +
month + ": " + average);
}
}
}

 

 

ArrayList類
在不知道數組大小的情況或運行時數組大小要改變的情況下,靜態數組就不是那麼有用了。
一個解決方是用一個空間不夠用時可以自增長的數群組類型,這個數組就是ArrayList,它也是System.Collections裡的一部分。
ArrayList類的對象有一個Capacity屬性用來儲存數組大小,初使值是16,當數組的元素接近16個時,Capacity會加16,
當然同時數組空間也變大了。需要用ArrayList的情況是這樣的:數組可能會變大或變小時,它比在標準數組裡用ReDim更高效。
這個第一章也說過,ArrayList儲存的是物件類型,如果需要強型別數組,你應該用標準數組或其他資料結構。 

以下是些常用的方法或屬性:
Add(): 向ArrayList添加一個元素.
AddRange(): 向ArrayList添加一組元素.
Capacity: 儲存ArrayList可以容納元素的個數
Clear(): 從ArrayList中移除一個元素.
Contains(): 判斷是否有指定的元素存在於ArrayList.
CopyTo(): 複製ArrayList或是ArrayList的一部分到一個Array類.
Count: 返回ArrayList內的元素個數.
GetEnumerator(): 返回一個ArrayList的迭代器.
GetRange(): 返回ArrayList的一個子集.
IndexOf(): 返回第一個發現的指定元素的索引.
Insert(): 向ArrayList的指定位置插入一個元素.
InsertRange(): 向ArrayList的指定位置插入一組元素
Item(): 設定或取得某個指定位置的值.
Remove(): 移除第一個發現的指定元素.
RemoveAt(): 移除指定位置的元素.
Reverse(): 逆序.
Sort(): 按字母排序.
ToArray(): 複製所有元素到一個Array類.
TrimToSize(): 將Capacity值設定成與數組元素個數相等的值.

 

使用ArrayList類
ArrayList不像標準的數組。一般來說,添加元素用Add(),除非在特定位置添加,那就用Insert()。
這裡,我們測試一下怎麼使用ArrayList的其他方法。
首先聲明一個對象ArrayList grades = new ArrayList();
注意這裡用了建構函式,如果ArrayList沒有用建構函式,這個ArrayList對象就不能使用。
用Add方法添加元素,這個方法只有一個參數,就是要添加到ArrayList的對象。
Add方法有傳回值,返回的插入的位置,只是很少用而已。下面是例子:
grades.Add(100);
grades.Add(84);
int position;
position = grades.Add(77);
Console.WriteLine("The grade 77 was added at position:
" + position);

 

 

ArrayList對象可以用Foreach來遍曆,ArrayList有一個內建的列舉程式
int total = 0;
double average = 0.0;
foreach (Object grade in grades)
total += (int)grade;
average = total / grades.Count;
Console.WriteLine("The average grade is: " + average);

 

如果你要添加元素到特定位置,用Insert方法,有兩個參數,位置和值
grades.Insert(1, 99);
grades.Insert(3, 80);

 

查看ArrayList當前的容量可以用Capacity屬性,看數組個數可以用Count屬性
Console.WriteLine("The current capacity of grades is:
" + grades.Capacity);
Console.WriteLine("The number of grades in grades is:
" + grades.Count);

 

這裡有些其他的方法移除元素,如果你知道要移除的元素,但不知道位置,用Remove方法,只有一個參數,就是這個你要移除的對象。
如果這個對象存在於ArrayList中,會被移除,否則,什麼都不做。就像是以下的代碼。
if (grades.Contains(54))
grades.Remove(54)
else
Console.Write("Object not in ArrayList.");

 

如果知道要移除的對象的位置,用RemoveAt方法,這個方法有一個參數:對象的索引。
如果傳入無效的索引則會異常。
grades.RemoveAt(2);

 

取得一個對象的索引用IndexOf方法,有一個參數,就是這個對象。返回這個對象的索引。如果不存在,返回-1
int pos;
pos = grades.IndexOf(70);
grades.RemoveAt(pos);

 

如果要添加對象集合的話,這組對象必須派生自ICollection,意思是說,這組對象可以存在於數組,Collection或者ArrayList裡。
這裡有兩個不同的方法去添加一組對象到ArrayList。AddRange和InsertRange,AddRange添加元素到末尾,InsertRange方法添加到指定位置。

(代碼如下)

 

結果如下

 

前面兩個名字在ArrayList的開頭是因為指定的索引是0.最後的那些名字在末尾是因為用的AaddRange。
還有兩個常用的方法是ToArray和GetRange方法。GetRange方法返回ArrayList裡的一組對象做為新的ArrayList。
ToArray方法複製所有元素到一個array元素

GetRange方法有兩個參數:開始的索引和要取得的元素個數。
GetRange方法沒有破壞性,只是取複本而已。下面是例子代碼

ArrayList someNames = new ArrayList();
someNames = names.GetRange(2,4);
Console.WriteLine("someNames sub-ArrayList: ");
foreach (Object name in someNames)
Console.WriteLine(name);

 

總結:

數組是最常用的資料結構。幾乎所有的程式設計語言都內建了數群組類型。
很多應用程式裡,數組是最簡單最有效資料結構,數組是很有用的。
.net有一個新的數群組類型叫做ArrayList,基本上和數組差不多,但更強的是它可以重新設定容量。
ArrayList還有一些很有用的方法,比如插入,刪除,以及尋找。
因為C#不允許程式員像VB.net那樣動態變更數組的大小,ArrayList在不知道數組大小的情況下是很有用的資料結構。

 

C#&&數組

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.