(原创)c#学习笔记05--变量的更多内容02--复杂的类型变量03--数组

5.2.3  数组

  前面的所有类型都有一个共同点:它们都只存储一个值(结构中存储一组值)。有时,需要存储许多数据,这样就会带来不便。有时需要同时存储几个类型相同的值,而不是每个值使用不同的变量。

  例如,假定要对所有朋友的姓名执行一些操作。可以使用简单的字符串变量,如下所示:

string friendName1 = "Robert Barwell"; 
string friendName2 = "Mike Parry"; 
string friendName3 = "Jeremy Beacock";

  但这看起来需要很多工作,特别是需要编写不同的代码来处理每个变量。例如,不能在循环中迭代这个字符串列表。

  另一种方式是使用数组。数组是一个变量的索引列表,存储在数组类型的变量中。例如,有一个数组 friendNames 存储上述的 3 个名字。在方括号中指定索引,即可访问该数组中的各个成员,如下所示:

friendNames[<index>] 

  这个索引是一个整数,第一个条目的索引是0,第二个条目的索引是1,依此类推。这样就可以使用循环遍历所有元素,例如:

      int i; 
      for (i = 0; i < 3; i++) 
      { 
          Console.WriteLine("Name with index of {0}: {1}", i, friendNames[i]); 
      }

  数组有一个基本类型,数组中的各个条目都是这种类型。 friendNames数组的基本类型是字符串,因为它要存储string变量。数组的条目通常称为元素。

1. 声明数组

  以下述方式声明数组:

<baseType>[] <name>; 

  其中,<baseType>可以是任何变量类型,包括本章前面介绍的枚举和结构类型。数组必须在访问之前初始化不能像下面这样访问数组或给数组元素赋值:

      int[] myIntArray; 
      myIntArray[10] = 5; 

  数组的初始化有两种方式。可以以字面形式指定数组的完整内容,也可以指定数组的大小,再使用关键字new初始化所有数组元素。

  使用字面值指定数组,只需要提供一个用逗号分隔的元素值列表,该列表放在花括号中,例如:

int[] myIntArray = { 5, 9, 10, 2, 99 }; 

  其中,myIntArray有5个元素,每个元素都被赋予了一个整数值。

  另一种方式需要使用下述语法:

int[] myIntArray = new int[5];

  这里使用关键字new显式地初始化数组,用一个常量值定义其大小。这种方法会给所有的数组元素赋予同一个默认值,对于数值类型来说,其默认值是 0。也可以使用非常量的变量来进行初始化,例如:

int[] myIntArray = new int[arraySize]; 

  还可以使用这两种初始化方式的组合:

int[] myIntArray = new int[5] { 5, 9, 10, 2, 99 };

  使用这种方式,数组大小必须与元素个数相匹配。例如,不能编写如下代码:

int[] myIntArray = new int[10] { 5, 9, 10, 2, 99 }; 

  其中数组定义为有10个元素,但只定义了5个元素,所以编译会失败。如果使用变量定义其大小,该变量必须是一个常量,例如:

      const int arraySize = 5; 
      int[] myIntArray = new int[arraySize] { 5, 9, 10, 2, 99 };

  如果省略了关键字const,运行这段代码就会失败。

  与其他变量类型一样,不见得在声明行中初始化数组。下面的代码是合法的:

      int[] myIntArray; 
      myIntArray = new int[5];

  需要确保使用前已经初始化。

  看个示例,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ch05Ex04
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] friendNames = { "Robert barwell", "Mike Parry", "Jeremy Beacock" };
            int i;
            Console.WriteLine( "Here are {0} of my friends:", friendNames.Length );
            for( i = 0; i < friendNames.Length; ++i ) {
                Console.WriteLine( friendNames[i] );
            }
            Console.ReadKey();
        }
    }
}

  运行结果如下:

  使用friendNames.Length来确定数组中元素的个数。

  记住,数组索引从 0 开始,所以最后一个元素是friendNames[2]。如果试图访问超出数组大小的元素,代码就会出问题。还可以通过一个更具弹性的方法来访问数组的所有成员,即使用foreach循环。

2. foreach循环

  foreach循环可以使用一种简便的语法来定位数组中的每个元素:

      foreach (<baseType> <name> in <array>) 
      { 
          // can use <name> for each element 
      }

  这个循环会迭代每个元素,依次把每个元素放在变量<name>中, 且不存在访问非法元素的危险。

  使用这个循环,可以修改上一个示例中的代码,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ch05Ex04
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] friendNames = { "Robert barwell", "Mike Parry", "Jeremy Beacock" };
            int i;
            Console.WriteLine("Here are {0} of my friends:", friendNames.Length);
            foreach (string friendName in friendNames)
            {
                Console.WriteLine(friendName);
            }
            Console.ReadKey();
        }
    }
}

  使用这种方法和标准的for循环的主要区别在于foreach循环对数组内容进行只读访问,所以不能改变任何元素的值

  如果使用简单的for循环,就可以给数组元素赋值。

3. 多维数组

  多维数组是使用多个索引访问其元素的数组。

  例如,假定要确定一座山相对于某位置的高度,可以使用两个坐标 x 和 y 来指定一个位置。把这两个坐标用作索引,数组 hillHeight 就可以用每对坐标来存储高度,这就要使用多维数组了。

  像这样的二维数组可以声明如下:

<baseType>[,] <name>;

  多维数组只需要更多的逗号,例如:

<baseType>[,,,] <name>;

  该语句声明了一个4维数组。赋值也使用类似的语法,用逗号分隔大小。要声明和初始化二维数组hillHeight,其基本类型是double,x的大小是3,y的大小是4,则需要:

 double[,] hillHeight = new double[3,4]; 

  还可以使用字面值进行初始的赋值。这里使用嵌套的花括号块,用逗号分隔开,例如:

double[,] hillHeight = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } }; 

  这个数组的维度与前面的相间,也是3行4列。通过提供字面值隐式定义了这些维度。

  要访问多维数组中的每个元素,只需指定它们的索引,并用逗号分隔开,例如:

 hillHeight[2,1] 

  接着就可以像其他元素那样处理它了。这个表达式将访问上面定义的第 3 个嵌套数组中的第 2个元素(其值是4)。记住,索引从0开始,第一个数字是嵌套的数组。换言之,第一个数字指定花括号对,第2个数字指定该对花括号中的元素。用图5-11来表示这个数组。

  foreach循环可以访问多维数组中的所有元素,其方式与访问一维数组相同,例如

      double[,] hillHeight = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } }; 
      foreach (double height in hillHeight) 
      { 
          Console.WriteLine("{0}", height); 
      }

  元素的输出顺序与赋予字面值的顺序相同(这里显示了元素的标识符,而不是实际值):

      hillHeight[0,0] 
      hillHeight[0,1] 
      hillHeight[0,2] 
      hillHeight[0,3] 
      hillHeight[1,0] 
      hillHeight[1,1] 
      hillHeight[1,2] 
      ...

4. 数组的数组

  上一节讨论的多维数组可称为矩形数组,这是因为每一行的元素个数都相同

  也可以使用锯齿数组(jagged array),其中每行都有不同的元素个数。为此,需要有这样一个数组,其中的每个元素都是另一个数组。也可以有数组的数组的数组,甚至更复杂的数组。但是,注意这些数组都必须有相同的基本类型

  声明数组的数组,其语法要在数组的声明中指定多个方括号对,例如:

 int[][] jaggedIntArray; 

  但初始化这样的数组不像初始化多维数组那样简单,有两种方式:可以初始化包含其他数组的数组(为了清晰起见,称之为子数组),然后依次初始化于数组:

      jaggedIntArray = new int[2][]; 
      jaggedIntArray[0] = new int[3]; 
      jaggedIntArray[1] = new int[4];

  也可以使用上述字面值赋值的一种改造形式:

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

  也可以进行简化,把数组的初始化和声明放在同一行上,如下所示:

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

  对锯齿数组可以使用foreach循环,但通常需要使用嵌套方法,才能得到实际数据。例如,假定下述锯齿数组包含10个数组,每个数组又包含一个整数数组,其元素是1~10的约数:

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

      foreach (int[] divisorsOfInt in divisors1To10) 
      { 
          foreach(int divisor in divisorsOfInt) 
          { 
              Console.WriteLine(divisor); 
          } 
      }

  

posted @ 2015-10-26 14:37  星月相随  阅读(410)  评论(0编辑  收藏  举报