7.1 Diksam中数组的设计

由于Diksam book_ver.0.1不能使用数组,因此让人感觉不太实用,所以在book_ver.0.2中我们将引入数组的概念。啊,这个开场白好像和4.1节的一样呢。

7.1.1 声明数组类型的变量

Diksam中数组的设计与Java大致相同。

首先,在Diksam中变量必须要进行声明,当然数组类型的变量也不例外,需要用Java的风格进行声明。

int[] a;// 声明int类型的数组

创建数组时的语法也和Java一样。

// 创建了一个可以访问到a[2][4]的数组

a = new int[3][5];

与crowbar和Java一样,Diksam的数组也是引用类型。因此,下面的代码会输出 a[1]..10。

int[] a = {1, 2, 3};

int[] b = a;// a和b指向同一个数组

//因此,改变b[1]的话a[1]也会跟着改变

b[1] = 10;

print("a[1].." + a[1] + "\n");

因为数组 a和数组 b指向了同一个数组,所以输出这样的结果也是理所当然的(如图7-1)。

figure_0226_0061

图7-1 两个变量同时引用一个Diksam的数组

另外,(看上去是)多维数组实际上是数组的数组。

总之,在 a = new int[3][5];这段代码中, a最后得到的是“ int数组(3个元素)的数组(5个元素)”。关于数组元素的引用形式,如图7-2所示。

figure_0227_0062

图7-2 Diksam的多维数组

7.1.2 数组常量

在Java中,数组类型变量只有在声明的同时进行初始化,才可以用如下方式。

int[] a = {1, 2, 3};

其他情况下,数组常量必须使用以下方式声明。

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

虽然知道在Java(或Diksam)这样的静态类型语言中必须明确地指定类型,但是总觉得 new int[]这部分太冗长了,另外对于初学者来说,初始化和其他情况不同也容易造成混乱。更重要的是我(从语言实现者的角度出发)不支持一种常量有两种声明方式。

因此在Diksam中,数组常量的类型由“最初的元素的类型”决定(这里模仿的是D语言)。

总之,下面这段代码中第2个和第3个元素会被转换成double,以double型数组{1.0, 2.0, 3.0}的形式赋值给a。

double[] a = {1.0, 2, 3}

第2 和第3个元素会被转换为 double,被赋值给 a 的是一个由 {1.0, 2.0, 3.0}组成的double数组。

在Diksam 中(与Java 相同),还没有决定元素值的数组,写作 a = new int[5][3];,这段代码创建了一个访问范围是从 a[0][0]到 a[4][2]的数组。

补充知识 D语言的数组

D语言是Digital Mars公司作为C语言的后继开发出来的编程语言。

在D语言中,如果想要创建一个访问范围从 a[0][0]到 a[4][2]的数组,就要写成 int[3][5];。而且,并不是堆中而是作为静态或者局部变量时数组的声明语法。如果要使用 new进行动态分配时就要写成 new int[3][5]了。

与C和Java一样,D语言的数组下标也是从0开始,下标的上限和数组的大小相差1。这点虽然很好,但是可以访问到 a[4][2]的数组声明方式却是 int[3][5];,肯定有人会怀疑是不是把顺序搞错了。确实,在C语言中可以访问到 a[4][2]的数组声明方式是 int[5][3];,Java在 new数组的时候也是 int[5][3];。

但是,在Java(或者是Diksam)中, new int[5][3];得到的是 int的数组(3个元素)的数组(5个元素)。Java(或者是Diksam)的语法不可以从左边开始读,这点在D语言中正好相反。

虽然是这样,但是Java语言比D语言使用范围更广泛,这部分的语法C#和Java也是相同的,更重要的是,已经习惯了这样(Java)的写法突然改变的话,会变得混乱(我自己也会),因此在数组声明方式上,Diksam是迎合了Java的做法。

虽然如此,D语言是美国人开发出来的语言,在他们看来D语言这样的顺序可能更自然一点。