《随笔十二》——C#中的 “ 一维数组、矩形数组、交错数组(锯齿数组)”

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34536551/article/details/84315919

目录

数组的类型

数组是对象

定义和初始化一维数组

定义和初始化矩形数组

初始化和定义交错数组(锯齿数组)

交错数组中的矩形数组

比较矩形数组 和交错 数组


●   数组实际上是由一个变量名称表示的一组同类型的数据元素,是一组相同类型的集合。 我们首先了解一下数组中的一些重要定义开始:

秩/ 维度 : 数组可以有任何为正数的维度数, 数组的维度称作秩。 意思就是说,该数组是几维数组 ,[  ] 表示一维数组, [ , ]  表示二维数组。

维度长度: 数组的每一个维度的长度, 就是这个方向的位置的元素个数.

数组长度: 数组的所有维度中的元素的总和称为数组的长度。

●   注意点:

数组一旦创建并且初始化,大小就固定了,C# 不支持动态数组。

数组的索引从0开始。那么数组中的元素个数的索引范围是 从0 到 n-1


数组的类型


●  C#中有两种类型的数组,分别为一维数组和多维数组,多维数组中还分矩形数组和 交错数组(也称为 锯齿数组)。

一维数组: 指的是一组地址连续的相同类型的单行元素序列。

多维数组:有多个秩,其中每一行的元素个数都相同。 不管多少维度,总是使用一个方括号,例如:

 ​​​​​​​ doule[,] myDouble = new double[3,4];

交错数组(也称为 锯齿数组):有多个秩,其中每一行的元素个数不一定都相同。然后呢,为数组的每一个维度使用一对方括号:


 int[][] myInt = new int[3][] { new int[] { 1, 2, 3 }, new int[] { 1 }, new int[] { 1, 2 } }; //正确

该数组就是:

1  2  3  // 第一行

1         // 第二行
 
1 2 


数组是对象


●   数组的实例是从 System.Array 继承的对象。那么数组是引用类型, 数组的引用在栈上或者堆上, 数组的元素总是在堆上。如图:


●  数组虽然是引用类型, 但是数组的元素 可以是值类型, 也可以是引用类型(比如类)。

如果存储的元素都是值类型, 数组被称为值类型数组。

如果存储的元素都是引用类型对象, 该数组被称为 引用类型数组。


定义和初始化一维数组


●  数组在必须在访问之前初始化,不能像这样访问数组或者给数组元素赋值:

int[] myIntArray;
myIntArray[10] = 5;  //错误, 该数组没有初始化

●  数组初始化的第一种方式是:用字面值形式指定数组的完整内容。该数组的长度编译器可以通过数组中的元素个数来推断长度。

int [] array= {0,1,2,3,4,5};

● 第二种方式是:指定数组的大小,然后使用new来初始化数组,但是该数组的每一个元素都被自动初始化为该数组类型的默认值。 对于预定义类型, 整型默认为 0,浮点型默认值为0.0, 布尔型默认值为 false,  引用类型 默认值为 null。

int []intArr =new int[4];
该数组执行的是默认初始化,并没有真正的初始化


● 第三种方式是:组合上面的初始化方式:

int [] array = new int[5] {0,1,2,3,4};
 
int [] array = new int[10] {0,1,2,3,4}; //错误

注意:使用这样的方式数组的大小与元素个数必须一致,否则错误。

● 第四种方式是:组合上面的初始化方式: 这样就不必输入数组的长度, 编译器可以通过元素个数来判断。

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

● 第五种方式是:也可以使用非常量的变量来进行初始化(c++ 中不可以这样):

int a = 6;
int[] array = new int[a]; //输出 6个0

int a = 6;
int[] array = new int[a];
array[0] = 12; //给第一个元素,初始化
for (int tt = 0; tt < a; ++tt)
{
   array[tt] = tt * 1;  // 循环给每一个元素初始化
}

● 第六种方式是:如果想使用非常量的变量来进行初始化,并且同时指定数组元素的初始值,那么该变量,必须是个常量:

const int arraySize = 5;
int[] myIntArray=new int[arraySize] {0,1,2,3,4};
 
 
const int arraySize = 4;
 int[] myIntArray = new int[arraySize] { 0, 1, 2 }; //错误,数组大小和元素个数不一致

如果省略了关键字const,语法错误。注意:  这样写,数组的大小与元素个数必须一致,否则错误。


定义和初始化矩形数组


 ●  要显式初始化矩形数组,需要注意的有:

每一个初始值元素必须封闭在大括号内。

每一个维度也必须嵌套并封闭在大括号内。

除了初始值,每一个维度的初始化列表和组成部分也必须使用逗号分隔。

矩形数组初始化的第一种方式:

  int[,] array = new int[,] { { 10,1},{ 2,10},{ 11,9} };

第二种方式:

    ​​​​​​​ double[,] myDouble = new double[3, 4];

第三种方式:这个通过字面值赋值,隐式定义了数组的维度。


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

第四种方式:

int c = 3, a = 4;
int[,] myInt = new int[c, a];  //正确

第五种方式:

             const int a = 3;
            const int b = 2;
            int[,] array = new int[a, b] { { 10, 1 }, { 2, 10 }, { 11, 9 } };

第六种方式:

 ​​​​​​​ double[,] myDouble = new double[3,4] { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } };

其实初始化的方式跟一维数组的类似,只是维数不同罢了。


隐式类型数组 (var关键字)


 ●  数组可以是隐式类型的,比如:

当初始化数组时,我们使用关键字 var, 可以让编译器根据初始化语句的类型来推断数组类型。

             int[] arr = new int[] { 10, 20 }; //一维数组
            var arr2 = new[] { 10, 20, 30 };

            int[,]arr3=new int[,]{ { 1,2},{ 2,4} };
            var arr4=new[,] { { 1, 2 }, { 2, 4 } };

注意: 在隐式类型 arr4 声明中, 我们仍然需要在初始化中提供 秩说明符。

看一个小代码:

           var myDouble =new[,] { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } };
            foreach (double height in myDouble)
            {
                WriteLine(height);
            }

初始化和定义交错数组(锯齿数组)


 ●  还有交错数组,其中每行的元素个数可能不同,其中的每一个元素都是包含另外一个数组。但是注意:这些数组都必须有相同的基本类型。 例如:

 int[][] jagArr = new int[3][];

 ●   交错数组的声明语法要求每一个维度都要有一对独立的方括号。 方括号的数量决定了交错数组的维度。

交错数组可能的维度可以是大于1的任意整数。

和矩形数组一样, 在数组类型的[ ] 号中不允许写数组的维度长度。

int[][] arr; //维度是2

 ●  交错数组第一种初始化方式:

 int[][] jagArr = new int[3][];

不能这样声明:

int[][] myInt =new[3][4];

也不可以这样:

 int[][] myInt = { { 1, 3, 4 }, { 2, 3, 4, 5 }, { 22, 3 } };

 ● 第二种初始化方式: 

            int[][] Arr = new int[3][]; //实例化顶层数组
//在数组下标为0的位置, 该位置有又是一个数组,里面有2个数字,元素个数不可以多,也不可以少
            Arr[0] = new int[2] { 10, 20}; //实例化顶层数组
            Arr[1] = new int[4] { 40, 2, 3, 4 };  //实例化子数组
            Arr[2] = new int[5] { 1, 2, 3, 4, 5 }; //实例化子数组

 ● 第三种初始化方式:

             int[][] Arr = new int[3][];  //实例化顶层数组
            //在数组下标为0的位置, 该位置有又是一个数组,[]不指定子数组的维度,让编译器根据元素个数去判断
            Arr[0] = new int[] { 10, 20,30};  //实例化子数组
            Arr[1] = new int[] { 40, 50, 60, 70 }; //实例化子数组
            Arr[2] = new int[] { 80, 90, 100, 110, 120 }; //实例化子数组

在第二种和第三种初始化方式要注意的是: 在代码中, 每一个子数组的引用都赋值给了顶层数组的元素。

 ● 第四种初始化方式:


            int[][] myInt = new int[3][] { new int[] { 1, 2, 3 }, new int[] { 1 }, new int[] { 1, 2 } }; //正确
            foreach (int[] divisor in myInt)
            {
                foreach (int temp in divisor)
                {
                    WriteLine(temp);
                }
            }

该交错数组有三行,new int[] { 1, 2, 3 } 表示,数组下标为0的地方有3个元素, new int[] { 1 } 表示数组下标为1的地方有1个元素,new int[] { 1, 2 } }表示数组下标为2的地方有2个元素.  最后使用嵌套的 foreach 循环输出 交错数组全部元素。

第五种初始化方式:

             int[][] myInt = { new int[] { 1, 2, 3 }, new int[] { 1 }, new int[] { 1, 2 } }; //正确
            foreach (int[] divisor in myInt)
            {
                foreach (int temp in divisor)
                {
                    WriteLine(temp);
                }
            }

交错数组中的矩形数组


 ●   由于交错数组中的子数组本身就是数组, 因此交错数组中也可能有矩形数组。 第六种初始化方式:

namespace HelloWorld_Console
{
 
    class Program
    {
        static void Main(string[] args)
        {

                   
          int[][,] Arr = new int[3][,];  // 实例化带有3个二维数组的交错数组
            Arr[0] = new int[,] { { 10, 20 },
                            { 100, 200 } };

            Arr[1] = new int[,] { { 30, 40, 50 },
                            { 300, 400, 500 } };

            Arr[2] = new int[,] { { 60, 70, 80, 90 },
                            { 600, 700, 800, 900 } };

            for (int i = 0; i < Arr.GetLength(0); i++)
            {
                for (int j = 0; j < Arr[i].GetLength(0); j++)
                {
                    for (int k = 0; k < Arr[i].GetLength(1); k++)
                    {
                        Console.WriteLine
                                 ("[{0}][{1},{2}] = {3}", i, j, k, Arr[i][j, k]);
                    }
                    Console.WriteLine("");
                }
                Console.WriteLine("");
            }
            ReadKey();
        }
    }
}

输出结果为:

[0][0,0] = 10
[0][0,1] = 20

[0][1,0] = 100
[0][1,1] = 200


[1][0,0] = 30
[1][0,1] = 40
[1][0,2] = 50

[1][1,0] = 300
[1][1,1] = 400
[1][1,2] = 500


[2][0,0] = 60
[2][0,1] = 70
[2][0,2] = 80
[2][0,3] = 90

[2][1,0] = 600
[2][1,1] = 700
[2][1,2] = 800
[2][1,3] = 900

代码中使用了数组的继承 System.Array 的GetLength (int n) 方法来获取数组中指定维度的长度。


比较矩形数组 和交错 数组


矩形数组和交错数组的结构区别非常大。下图演示了 3*3 的矩形数组以及一个由3 个长度为3 的一维数组构成的交错数组的结构。

首先两个数组都保存了9个整数, 但是它们的结构去很不同。

矩形数组只有单个数组对象, 而交错数组有4个数组对象 。

注意: 一维数组有特定的指令用于性能优化, 矩形数组没有这些指令, 并且不在相同级别进行优化。 因此, 有时使用一维数组(可以被优化)的交错数组比矩形数组(不能被优化) 更有效率。

​​​​​​​

猜你喜欢

转载自blog.csdn.net/qq_34536551/article/details/84315919