c#高級編程(第八版)-第六章數組隨筆

如果需要使用同一類型的多個對象,就可以使用集合和數組,c#使用特殊句號聲明和初始化數組,簡單來說需要時使用同一類型的多個對象時,就可以使用數組,數組是一種數據結構。

數組的聲明:

 int[] Array;

數組的初始化:

聲明數組後必須給數組分配內存,以保存數組的所有元素,數組是引用類型,所以必須給他分配堆上內存,因此使用new運算符。             數組聲明的的方式。

int[] Array=new int[];

初始化的三種方式:

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

在聲明和初始化數組後就可以使用索引器訪問數組的元素了,數組只支持有整型參數的索引器,通過索引便可以訪問其中的元素(從0開始)。

int[] Array={1,2,3,4};

Array[0]=1,  Array[3]=4;

如果不知道數組的元素個數可以用Length屬性,下面兩種也是取數據的方式

for(int i=0;i<Array.length;i++)
{
   int a=Array[i];
}
foreach(int b in Array)
{
   int a=b;
}

引用類型數組

除了能聲明預定義類型的數組外,還可以聲明自定義類型數組

public class Person
{
  public string FirstName;
   public string LastName;
}

數組聲明:

person[] Array=new person[2];

數組初始化::

和int類型一樣。

person[]  Array=new person[2]{new person{FirstName="大衛",LastName="菠蘿"},new person{FirstName="小衛",LastName=“土豆”}};

其實引用類型的數組和int類型數組一樣,只不過把類型換了一下而已。

多維數組

一般數組(一維數組)用一個整數來索引,多維用兩個或者多個整數來索引。

二維數組聲明

int[,] Array=new int[2,3](代表2行3列的數組)。

二維數組初始化

int[,] Array=new int[]{{1,2},{1,3},{1,4}}//(代表3行2列的數組)。
//取值,索引從0開始
Array[0,0]=1;
Array[0,1]=2;

3維數組及以上,還有鋸齒數組都差不多,就不討論了。

Array類

用方括號聲明數組是c#中使用Array類的表示法,在後臺使用c#語法,會創建一個派生自抽象基類Array的新類,這樣就可以使用Array爲每個c#數組定義的方法和屬性了,,例如前面使用的Length屬性,或者是foreach語句來迭代數組,其實使用了Array類中的GetEnumerator()方法。(我的理解就是數組可以使用Array類中的屬性和方法).

Array類實現的其他屬性有longlength和rank,longlength表示所有維數中元素的個數,rank表示維數。

Array類是抽象類,所以不能構造函數來創造數組,但是可以用靜態方法來CreateInstance()方法來創建數組,如果事先不知道元素類型就很有用,因爲類型可以當做參數傳進去。

//創建一個類型爲int,大小爲5的數組
Array IntArray=Array.CreateInstance(typeof(int),5);
//賦值
for(int i=0;i<IntArray.length;i++)
{
    IntArray.SetValue(33,i);//後面i爲索引
}
//取值
for(int i=0;i<IntArray.length;i++)
{
    int a= IntArray.GetValue(i);
}

引用數組,鋸齒數據,多維數組同樣可以用Array.CrueateInstance方法來創建,則不再討論。

複製數組

因爲數組是引用類型,所以將一個數組賦值爲另外一個數組,就會等到兩個引用同一數組的變量,複製數組會實現ICloneable接口,這個接口定義的Clone()方法會創建數組的淺表副本(我的理解就是 數組 a=數組 b 改變數組a的值,b也會跟着改變,數組 a=數組b.clone()改變a的值不會改變b的值)

排序

Array類使用QuickSort算法對數組中的元素進行排序,Sort()方法需要數組中元素實現Icomparable接口

int[] Array={3,2,1};
Array.sort(Array);
//從小到大排序,則Array裏數據排序
Array[0]=1;
Array[1]=2;
Array[2]=2;

引用類型數組排序就不在這裏介紹了,沒有封裝好的方法,需要自己寫。

數組作爲參數

int[] Array={1,2,3};
static void TestArray(int[] pram)
{
   //....... 函數體
}
//數組協邊,即數組也可以聲明爲基類(通俗點就是object[] 可以傳數組)
static void TestArray(object[] pram)//可以傳引用類型的數組
{
   //....... 函數體
}

數組協變,只能用於引用類型,不能用於值類型,數組協邊有個問題,他只能通過運行時異常來解決,如果把引用數組賦予object[]數組,object數組就可以使用使用派生自object的任何元素。(不建議用object[])。

ArraySegment<T>

結構ArraySegment<T>表示數組的一段,如果需要使用不同的方法處理某個大型方法的不同部分,則需要將相應的部分傳到相應的方法中,更有效的是使用一個數組,將整個數組傳遞到不同方法去。

//舉個簡單的例子,若有兩個不同的數組,選取不同的部分求和,則可以使用Arraysegment
static int SumOfSegment(Arrsegement<int>[] segments)
{
  int sum=0;
 foreach(var segment in segments)
 {
   for(int=segment.offest;i<segment.offset+segment.count;i++)
   {
    sum+=segment.array[i];
   }
 }
  return sum;
}
int[] a={1,2,3,4,5};
int[] b={2,3,4,5,6,7};
//數組a取出索引1,往後數兩個數的數(從索引開始算),數組b,取出索引1,往後數3個數的數(從1開始算),a 取出2,3,b取出3,4,5
static void TestSegMent()
{
   ArraySegment<int>[] segments=new ArraySegment<int>[2]{new ArraySegment<int>(a,1,2),new ArraySegment<int>(b,1,3)};//將不同數組的不同部分傳入segment中(自我感覺不咋用的到0.0)
   int sum=SumOfSegment(segments);
}

枚舉

在foreach語句中使用枚舉,可以迭代集合中元素,無須知道集合的個數,foreach使用了一個枚舉器。;數組或集合實現帶GetEumerator()方法的IEnumerable接口。

Tip:GetEnumerator()方法用IEnumerable接口定義,foreach語句並不真的需要在集合類中實現這個接口,有一個名爲GetEnumerator的方法,他返回了實現IEnumerator接口的對象就足夠了。

IEnumerator接口

foreach語句使用IEnumerator接口的方法和屬性,迭代集合中所有的元素,爲此IEnumerator定義了current屬性,來返回光標當前所在的元素。該接口的MoveNext()方法移動到集合的下一個元素,如果有這個元素就返回true,如果沒有下一個元素則返回false.該接口的泛型版本IEnumerator<T> 接口派生自IDisposable接口,因此定義了Dispose()方法,來清理枚舉器產生的資源。

Foreach語句

int[] array={1,2,3,4};
foreach(int a in array)
{
  console,writeline(a)
}
//上面的foreach等價於下面的枚舉器
IEnumeator<int> enumerator=array.GetEnumerator()//用getenumerator()方法獲得數組的一個枚舉器
while(enumerator.movenext())
{
  int p=enumerator.current;
  console.writeline(p);
}

Yield語句

c#2.0添加了yield語句,以便於創建枚舉器,yield return語句返回集合的一個元素,並移動到下一個元素上,yield back可以停止迭代。

 //返回hello world 
pubic IEnumerator<string> GetEnumerator()
{
  yield return "Hello";
  yield return "wrold";
}

tip:包含yeild語句的方法和屬性也被成爲迭代塊,迭代塊必須聲明爲返回IEnumerator或者IEnumerable接口,或者這些接口的泛型版本。這個快可以包含多個yeild return和yeild back語句,但是不能包含return語句.

元組

元組的初始化

//元組初始化時應設值否則會報錯
Tuple<int,string> tuple=new Tuple<int,string>(1,"2");
//或者下一種
Tuple<int,string> tuple=new Tuple<int,string>(1,"2");

 

數組是和並相同類型的成員,元組是合併不同類型的成員。,net定義了8個泛型的Tuple類和一個靜態Tuple類,例如Tuple<T1>包含一個元素,Tuple<T1,T2>包含了兩個元素。

public Static Tuple<int,string> Divide(int a,int b)
{
  int result1=a+b;
  int result=(a-b).tostring();
  return Tuple.Create<int,int>(result1,reult2);
}
public static Test()
{
  Tuple<int,string> tuple= Divide();
  int a=tuple.item1;//第一個數
string b=tuple.item2;//第二個數
}

Tip:如果元祖包含的項超過8個,就可以用帶8個參數的Tuple類定義,最後一個模板參數是TRest表示必須給它傳遞一個元組,舉個例子

//當元組包含的項超過8個時,最後一個模板必須是元組
var tuple = new Tuple<int, int, int, int, int, int, int, Tuple<int, string>>(1, 1, 1, 1, 1, 1, 1, Tuple.Create<int, string>(1, "2"));
//或者下一種
var tuple2 = new Tuple<int, int, int, int, int, int, int, Tuple<int, string>>(1, 1, 1, 1, 1, 1, 1, new Tuple<int, string>(1,"2"));

(自我感覺元組的使用就是當類中的元素少的時候,可以用元組替代,簡化代碼)。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章