编程实践(一些令人困惑的陈述)

时间:2013-10-29 10:09:16

标签: java arrays search

前几天我正在阅读Kernighan和Rob Pike的编程实践

在第二章中,在搜索部分下,我读到了一些在我脑海中造成混淆的行。

"没有什么比用于存储静态表格数据的数组更好。编译时初始化 使得构造这样的数组变得便宜和容易。 (在Java中,初始化发生在 运行时,但这是一个不重要的实现细节,除非数组很大。)"

我的问题是,如果用户只在运行时提供数组或变量的编译时初始化,并且变量的内存分配在运行时发生,那么在任何语言中如何都可以进行编译时初始化。不知道内存地址如何初始化数组?

3 个答案:

答案 0 :(得分:1)

它没有说数据是在运行时提供的。它只是说“静态”数据。如果在编译时已知,则编译器可以将其编译到代码中。 API密钥,带有“幻数”的表或错误消息文本符合该模式。

答案 1 :(得分:1)

我认为你误解了作者所说的话。注意:

这是一个静态数组,在Java中:

String[] suit = {
  "item 1", 
  "item 2", 
  "item 3", 
  "item 4"  
};

现在,Java不允许您声明真正的动态数组,如Delphi和其他语言,对于动态数组,我们必须选择另一个名为ArrayList的数据结构,如下例所示:< / p>

List<String> list = new ArrayList<String>();

如果用户想要使用具有运行时定义长度的静态数组,他可以做的最灵活的方法如下:

int maxsize = Integer.ParseInt(JOP.ShowInputDialog("give me a number")...);
int[] myArray = new int[maxsize]();

这是Delphi中的静态数组:

const MyStaticArray : array [0..3] of Integer = (0, 1, 2, 3);

这是动态数组

var MyDinamicArray : array of Integer; 
    MaxSize: Integer;
begin
  MaxSize := StrToInt(InputBox(..,'Give me a number', ..));
  SetLength(MyDinamicArray, MaxSize); //Defines the array size, in runtime;
end;
  

我的问题是,如何使用任何语言进行编译   如果用户要去的话,数组或变量的时间初始化   仅在运行时提供它以及为内存分配   变量在运行时发生。不知道内存地址   如何初始化数组?

也就是说,我们可以很容易地看到,这是一个“编译时”初始化(与实现细节无关)

String[] suit = {
  "item 1", 
  "item 2", 
  "item 3", 
  "item 4"  
};

一旦阵列初始化,不能调整大小,因此操作系统可以在任何需要的地方分配内存。由于数组在内存中是顺序,因此通过使用索引,Java知道您想要获取的地址。

考虑上面的数组,这是内存草图:

//程序存储器

address   00A1
value   | 00BA |
alias     suit 

// OS Memory

address      00BA      00BB       00BC       00BD      
value    | "item 1" | "item 2" | "item 3" | "item 4" | 
alias       suit[0]    suit[1]    suit[2]    suit[3]

这里的字符串使得它易于理解,实际上String也是指向某事物的指针。

别名是Java隐藏指针算法的方式,即允许我们访问索引而不是内存地址。

以下是有关数组的一些文档:

阅读Static Arrays并查看Array List

答案 2 :(得分:0)

来自JLS

10.2。数组变量

  

数组类型的变量包含对象的引用。 声明一个   数组类型的变量不会创建数组对象或分配任何数组   数组组件的空间。它只创建变量本身   可以包含对数组的引用。

     

然而,声明者的初始化部分(§8.3,§9.3,§14.4.1)   可以创建一个数组,一个引用然后成为初始数组   变量的值。