【问题标题】:The practice of programming (Some confusing statements)编程实践(一些令人困惑的陈述)
【发布时间】:2013-11-08 10:12:30
【问题描述】:

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

在第二章的搜索部分下,我读到了其中一些让我头脑混乱的行。

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

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

【问题讨论】:

    标签: java arrays search


    【解决方案1】:

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

    【讨论】:

    • 它是关于数组和数组在运行时提供的内存地址。如果事先不知道内存,如何进行初始化?
    • 如果编译成二进制,数组可以像函数一样放入内存:只需将位从磁盘加载到内存中。在 C 中,数组基本上只是一个内存指针,对吧?它指向的数据可能已经被编译器放在那里。
    【解决方案2】:

    我想你误解了作者的意思。注意:

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

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

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

    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 
    

    //操作系统内存

    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

    【讨论】:

    • 虽然这是对作者可能的意思的可靠解释,但我认为 OP 是作者误导,而不是像他们所说的那样误解了他们definition(指定某事的行为)而不是 initialization(在程序运行期间分配和创建适当的内存结构的行为,表示已定义的内容) .
    • @TheTerribleSwiftTomato 好吧,我没有读过这本书,我发布的是我对段落的解释,没有上下文我不能说别的。然后,我的建议是 OP 编辑​​他的问题以增加对该主题的完整性
    • 当然,我只是指出,如果书中使用了“编译时初始化”这个短语,那是不正确的。
    • 谢谢,很好的观察!
    【解决方案3】:

    来自JLS

    10.2.数组变量

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-26
      • 2014-10-17
      • 2012-01-02
      • 1970-01-01
      • 2022-01-21
      • 2022-01-17
      • 1970-01-01
      • 2018-02-26
      相关资源
      最近更新 更多