溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何理解C#數(shù)組

發(fā)布時(shí)間:2021-09-26 10:16:43 來(lái)源:億速云 閱讀:150 作者:柒染 欄目:開發(fā)技術(shù)

本篇文章為大家展示了如何理解C#數(shù)組,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

前言:

  如果需要使用同一類型的多個(gè)對(duì)象,可以使用數(shù)組和集合。C#用特殊的記號(hào)聲明,初始化和使用數(shù)組。Array類在后臺(tái)發(fā)揮作用,它為數(shù)組中的元素排序和過(guò)濾提供了多個(gè)方法。使用枚舉器,可以迭代數(shù)組中的所有元素。
  如果需要使用不同類型的多個(gè)對(duì)象,可以使用Tuple(元組)類型。

一.簡(jiǎn)單數(shù)組之一維數(shù)組  

    數(shù)組是一種數(shù)據(jù)結(jié)構(gòu),它可以包含同一個(gè)類型的多個(gè)元素。

1.數(shù)組的聲明  

      在聲明數(shù)組時(shí),先定義數(shù)組中的元素類型,其后是一對(duì)空方括號(hào)和一個(gè)變量名。

  int[] myArray;

2.數(shù)組的初始化

  聲明了數(shù)組之后,就必須為數(shù)組分配內(nèi)存,以保存數(shù)組的所有元素。數(shù)組是引用類型,所以必須給它分配堆上的內(nèi)存。為此,應(yīng)使用new運(yùn)算符,指定數(shù)組中元素的類型和數(shù)量來(lái)初始化數(shù)組的變量。

  myArray = new int[4];

  在聲明和初始化數(shù)組后,變量myArray就引用了4個(gè)整數(shù)值,它們位于托管堆上:

如何理解C#數(shù)組

   在指定了數(shù)組的大小后,就不能重新設(shè)置數(shù)組的大小。如果事先不知道數(shù)組中應(yīng)包含多少個(gè)元素,就可以使用集合。
  除了在兩個(gè)語(yǔ)句中聲明和初始化數(shù)組之外,還可以在一個(gè)語(yǔ)句中聲明和初始化數(shù)組:

  int[] myArray = new int[4];

  還可以使用數(shù)組初始化器為數(shù)組的每個(gè)元素復(fù)制。數(shù)組初始化器只能在聲明數(shù)組變量時(shí)使用,不能在聲明數(shù)組之后使用。

  int[] myArray = new int[4]{1,3,5,7};

  如果用花括號(hào)初始化數(shù)組,可以不指定數(shù)組的大小,因?yàn)榫幾g器會(huì)自動(dòng)統(tǒng)計(jì)元素的個(gè)數(shù):

  int[] myArray = new int[]{1,3,5,7};

  也可以使用更簡(jiǎn)單的形式:

  int[] myArray = {1,3,5,7};

3.訪問(wèn)數(shù)組元素

  在聲明和初始化數(shù)組之后,就可以使用索引器訪問(wèn)其中的元素了。數(shù)組只支持有整型參數(shù)的索引器。
  索引器總是以0開頭,表示第一個(gè)元素。可以傳遞給索引器的最大值是元素個(gè)數(shù)減1,因?yàn)樗饕龔?開始:

  int[] myArray = {1,3,5,7};
  int v1 = myArray[0];
  int v2 = myArray[1];
  myArray[3] = 4;

  可以使用數(shù)組的Length屬性獲取元素的個(gè)數(shù)。

4.數(shù)組中使用引用類型

  數(shù)組除了能聲明預(yù)定義類型的數(shù)組,還可以聲明自定義類型的數(shù)組。

 public class Person
  {
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public override string ToString()
    {
      return String.Format("{0} {1}", FirstName, LastName);
    }
  }

  Person[] myPersons = new Person[2];
  myPersons[0] = new Person { FirstName = "Ayrton", LastName = "Senna" };
  myPersons[1] = new Person { FirstName = "Michael", LastName = "Schumacher" };

  如果數(shù)組中的元素是引用類型,就必須為每個(gè)數(shù)組元素分配內(nèi)存。如果使用了數(shù)組中未分配內(nèi)存的元素,就會(huì)拋出NullReferenceException類型的異常。
  下面是內(nèi)存情況:

如何理解C#數(shù)組

    對(duì)自定義類型也可以使用數(shù)組初始化器:

  Person[] myPersons2 =
  {
    new Person { FirstName="Ayrton", LastName="Senna"},
    new Person { FirstName="Michael", LastName="Schumacher"}
  };

二.多維數(shù)組

  多維數(shù)組用兩個(gè)或多個(gè)整數(shù)來(lái)索引。
  在C#中聲明多維數(shù)組,需要在方括號(hào)中加上逗號(hào)。數(shù)組在初始化時(shí)應(yīng)指定每一維的大?。ㄒ卜Q為階)。

  int[,] twoDim = new int[3,3];
  twoDim[0,0] = 1;
  twoDim[0,1] = 2;
  twoDim[0,2] = 3;
  twoDim[1,0] = 4;
  twoDim[1,1] = 5;
  twoDim[1,2] = 6;
  twoDim[2,0] = 7;
  twoDim[2,1] = 8;
  twoDim[2,2] = 9;

  聲明數(shù)組之后,就不能修改其階數(shù)了。
  也可以使用初始化器來(lái)初始化多維數(shù)組:

  int[,] twoDim ={
    {1,2,3},
    {4,5,6},
    {7,8,9}
    };

  使用數(shù)組初始化器時(shí),必須初始化數(shù)組的每個(gè)元素,不能遺漏任何元素。
  聲明一個(gè)三位數(shù)組:

  int[,,] threeDim ={
    {{1,2},{3,4}},
    {{5,6},{7,8}},
    {{9,10},{11,12}}
    };
  Console.WriteLine(threeDim[0,1,1]);

三.鋸齒數(shù)組

  二維數(shù)組的大小對(duì)應(yīng)于一個(gè)矩形,而鋸齒數(shù)組的大小設(shè)置比較靈活,在鋸齒數(shù)組中,每一行都可以有不同的大小。
  在聲明鋸齒數(shù)組時(shí),要依次放置左右括號(hào)。在初始化鋸齒數(shù)組時(shí),只在第一對(duì)方括號(hào)中設(shè)置該數(shù)組包含的行數(shù)。定義各行中元素個(gè)數(shù)的第二個(gè)方括號(hào)設(shè)置為空,因?yàn)檫@類數(shù)組的每一行包含不同的元素個(gè)數(shù)。之后,為每一行指定行中的元素個(gè)數(shù):

  int[][] jagged = new int[3][];
  jagged[0] = new int[2]{1,2};
  jagged[1] = new int[4]{3,4,5,6};
  jagged[2] = new int[3]{7,8};

  迭代鋸齒數(shù)組中的所有元素的代碼可以放在嵌套的for循環(huán)中。在外層的for循環(huán)中迭代每一行,在內(nèi)層的for循環(huán)中迭代一行中的每個(gè)元素:

  for(int row = 0;row<jagged.Length;row++)
  {
    for(int element = 0;element<jagged[row].Length;element++)
    {
      Console.WriteLine("row:{0}, element:{1},value:{2}",row,element,jagged[row][element]);
    }
  }

四.Array類

  用方括號(hào)聲明數(shù)組是C#中使用Array類的表示法。在后臺(tái)使用C#語(yǔ)法,會(huì)創(chuàng)建一個(gè)派生自抽象基類Array的新類。這樣,就可以使用Array類為每個(gè)C#數(shù)組定義的方法和屬性了。
  Array類實(shí)現(xiàn)的其它屬性有LongLengthRank。如果數(shù)組包含的元素個(gè)數(shù)超出了整數(shù)的取值范圍,就可以使用LongLength屬性來(lái)獲得元素個(gè)數(shù)。使用Rank屬性可以獲得數(shù)組的維數(shù)。

1.創(chuàng)建數(shù)組

  Array類是一個(gè)抽象類,所以不能使用構(gòu)造函數(shù)來(lái)創(chuàng)建數(shù)組。但除了使用C#語(yǔ)法創(chuàng)建數(shù)組實(shí)例之外,還可以使用靜態(tài)方法CreateInstance()創(chuàng)建數(shù)組。如果事先不知道元素的類型,該靜態(tài)方法就很有用,因?yàn)轭愋涂梢宰鳛?code>Type對(duì)象傳遞給CreateInstance()方法。
  CreateInstance()方法的第一個(gè)參數(shù)是元素的類型,第二個(gè)參數(shù)定義數(shù)組的大小。
  可以使用SetValue()方法設(shè)置對(duì)應(yīng)元素的值,用GetValue()方法讀取對(duì)應(yīng)元素的值。

  Array intArray1 = Array.CreateInstance(typeof(int), 5);
  for (int i = 0; i < 5; i++)
  {
    intArray1.SetValue(33, i);
  }

  for (int i = 0; i < 5; i++)
  {
    Console.WriteLine(intArray1.GetValue(i));
  }
  

      還可以將已經(jīng)創(chuàng)建的數(shù)組強(qiáng)制轉(zhuǎn)換稱聲明為int[]的數(shù)組:

  int[] intArray2 = (int[])intArray1;

  CreateInstance()方法有許多重載版本,可以創(chuàng)建多維數(shù)組和索引不基于0的數(shù)組。

//創(chuàng)建一個(gè)2X3的二維數(shù)組,第一維基于1,第二維基于10:
  int[] lengths = { 2, 3 };
  int[] lowerBounds = { 1, 10 };
  Array racers = Array.CreateInstance(typeof(Person), lengths, lowerBounds);

 
  racers.SetValue(new Person { FirstName = "Alain", LastName = "Prost" }, index1: 1, index2: 10);
  racers.SetValue(new Person
  {
    FirstName = "Emerson",
    LastName = "Fittipaldi"
  }, 1, 11);
  racers.SetValue(new Person { FirstName = "Ayrton", LastName = "Senna" }, 1, 12);
  racers.SetValue(new Person { FirstName = "Michael", LastName = "Schumacher" }, 2, 10);
  racers.SetValue(new Person { FirstName = "Fernando", LastName = "Alonso" }, 2, 11);
  racers.SetValue(new Person { FirstName = "Jenson", LastName = "Button" }, 2, 12);

  Person[,] racers2 = (Person[,])racers;
  Person first = racers2[1, 10];
  Person last = racers2[2, 12];

2.復(fù)制數(shù)組

  因?yàn)閿?shù)組是引用類型,所以將一個(gè)數(shù)組變量賦予另一個(gè)數(shù)組變量,就會(huì)得到兩個(gè)引用同一數(shù)組的變量。
  數(shù)組實(shí)現(xiàn)ICloneable接口。這個(gè)接口定義的Clone()方法會(huì)復(fù)制數(shù)組,創(chuàng)建數(shù)組的淺表副本。

  如果數(shù)組的元素是值類型,Clone()方法會(huì)復(fù)制所有值:

  int[] a1 = {1,2};
  int[] a2 = (int[])a1.Clone();

  如果數(shù)組包含引用類型,只復(fù)制引用。

  除了使用Clone()方法之外,還可以使用Array.Copy()方法創(chuàng)建淺表副本。

 Person[] beatles = {
    new Person { FirstName="John", LastName="Lennon" },
    new Person { FirstName="Paul", LastName="McCartney" }
  };

  Person[] beatlesClone = (Person[])beatles.Clone();
  Person[] beatlesClone2 = new Person[2];
  Array.Copy(beatlesClone,beatlesClone2,2);//注意與Clone的語(yǔ)法區(qū)別,Copy需要傳遞階數(shù)相同的已有數(shù)組。(還可以使用CopyTo()方法)

3.排序

  Array類使用快速排序算法對(duì)數(shù)組中的元素進(jìn)行排序。Sort()方法需要數(shù)組中的元素實(shí)現(xiàn)IComparable接口。因?yàn)楹?jiǎn)單類型(如String,Int32)實(shí)現(xiàn)IComparable接口,所以可以對(duì)包含這些類型的元素排序。

    string[] names = {
    "Christina Aguilera",
    "Shakira",
    "Beyonce",
    "Gwen Stefani"
    };

    Array.Sort(names);

    foreach (string name in names)
    {
      Console.WriteLine(name);
    }


  如果對(duì)數(shù)組使用使用自定義類,就必須實(shí)現(xiàn)IComparable接口。這個(gè)接口只定義了一個(gè)方法CompareTo()方法,如果要比較的對(duì)象相等,該方法就返回0.如果該實(shí)例應(yīng)排在參數(shù)對(duì)象的前面,該方法就返回小于i0de值。如果該實(shí)例應(yīng)排在參數(shù)對(duì)象的后面,該方法就返回大于0的值。

  public class Person : IComparable<Person>
  {
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public override string ToString()
    {
      return String.Format("{0} {1}",
      FirstName, LastName);
    }

    public int CompareTo(Person other)
    {
      if (other == null) throw new ArgumentNullException("other");

      int result = this.LastName.CompareTo(other.LastName);
      if (result == 0)
      {
        result = this.FirstName.CompareTo(other.FirstName);
      }

      return result;
    }

  }

  客戶端代碼:

  Person[] persons = {
  new Person { FirstName="Damon", LastName="Hill" },
  new Person { FirstName="Niki", LastName="Lauda" },
  new Person { FirstName="Ayrton", LastName="Senna" },
  new Person { FirstName="Graham", LastName="Hill" }
  };
  Array.Sort(persons);
  foreach (Person p in persons)
  {
    Console.WriteLine(p);
  }

  如果Person對(duì)象的排序方式與上述不同,或者不能修改在數(shù)組中用作元素的類,就可以實(shí)現(xiàn)IComparer接口或IComparer<T>接口。這兩個(gè)接口定義了方法Compare()方法。機(jī)型比較的類必須實(shí)現(xiàn)這兩個(gè)接口之一。

  public enum PersonCompareType
  {
    FirstName,
    LastName
  }
  //通過(guò)使用實(shí)現(xiàn)了IComparer<T> 泛型接口的PersonComparer類比較Person對(duì)象數(shù)組。
  public class PersonComparer : IComparer<Person>
  {
    private PersonCompareType compareType;

    public PersonComparer(PersonCompareType compareType)
    {
      this.compareType = compareType;
    }


    #region IComparer<Person> Members

    public int Compare(Person x, Person y)
    {
        if (x == null) throw new ArgumentNullException("x");
        if (y == null) throw new ArgumentNullException("y");

      switch (compareType)
      {
        case PersonCompareType.FirstName:
          return x.FirstName.CompareTo(y.FirstName);
        case PersonCompareType.LastName:
          return x.LastName.CompareTo(y.LastName);
        default:
          throw new ArgumentException(
          "unexpected compare type");
      }
    }

    #endregion
  }

  客戶端代碼:

 Person[] persons = {
  new Person { FirstName="Damon", LastName="Hill" },
  new Person { FirstName="Niki", LastName="Lauda" },
  new Person { FirstName="Ayrton", LastName="Senna" },
  new Person { FirstName="Graham", LastName="Hill" }
  };
  Array.Sort(persons,
  new PersonComparer(PersonCompareType.FirstName));

  foreach (Person p in persons)
  {
    Console.WriteLine(p);
  }

五.數(shù)組作為參數(shù)

  數(shù)組可以作為參數(shù)傳遞給方法,也可以從方法中返回。

1.數(shù)組協(xié)變

  數(shù)組支持協(xié)變。這表示數(shù)組可以聲明為基類,其派生類型的元素可以賦值于數(shù)組元素。

  static void DisPlay(object[] o)
  {
    //..
  }

  可以給該方法傳遞一個(gè)Person[] 。
  數(shù)組協(xié)變只能用于引用類型,不能用于值類型。

2.ArraySegment<T>

  結(jié)構(gòu)ArraySegment<T>表示數(shù)組的一段。如果需要使用不同的方法處理某個(gè)大型數(shù)組的不同部分,那么可以把相應(yīng)的數(shù)組部分復(fù)制到各個(gè)方法。

  ArraySegment<T>結(jié)構(gòu)包含了關(guān)于數(shù)組段的信息(偏移量和元素個(gè)數(shù))。

  static void Main()
  {
    int[] ar1 = { 1, 4, 5, 11, 13, 18 };
    int[] ar2 = { 3, 4, 5, 18, 21, 27, 33 };
    var segments = new ArraySegment<int>[2]
    {
      new ArraySegment<int>(ar1, 0, 3),
      new ArraySegment<int>(ar2, 3, 3)
    };


    var sum = SumOfSegments(segments);
    Console.WriteLine("sum of all segments: {0}", sum);

  }

  static int SumOfSegments(ArraySegment<int>[] segments)
  {
  int sum = 0;
  foreach (var segment in segments)
  {
    for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
    {
        sum += segment.Array[i];
    }

  }
  return sum;
  }

  數(shù)組段不復(fù)制原數(shù)組的元素,但原數(shù)組可以通過(guò)ArraySegment<T>訪問(wèn)。如果數(shù)組段中的元素改變了,這些變化就會(huì)反映到原數(shù)組中。

上述內(nèi)容就是如何理解C#數(shù)組,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI