【问题标题】:How is an array type declaration 'new int[10][]' evaluated?如何评估数组类型声明“new int[10][]”?
【发布时间】:2010-02-10 19:00:57
【问题描述】:

a) 如何评估数组类型声明 new int[10][]?评估了吗

作为(new int[10])[]

(new int[10][])

还是……?

b) 我不知道怎么问这个问题:我知道语句 int[][] i = (new int[10])[] 会给我们编译器错误。但是假设编译器不会报错,那么编译器会根据这个语句创建什么样的数组类型呢?


已编辑:

对于未能让我的问题更全面,我深表歉意。这是困扰我的问题之一,我无法在脑海中将这个问题具体化到足以理解它的程度。所以我问了半个问题,希望回复能帮助我。无论如何,这是一个毫无意义的问题,但我仍然想解释一下我的实际意思:

促使这一切发生的原因是 MSDN 上的一篇文章

主表达式分为数组创建表达式和主无数组创建表达式。以这种方式处理数组创建表达式,而不是将其与其他简单的表达式形式一起列出,可以使语法禁止潜在的混淆代码,例如

object o = new int[3][1];

否则会被解释为

object o = (new int[3])[1];

所以这让我想到,也许围绕这个数组创建表达式的不同部分的括号会给编译器关于它应该创建的数组类型的不同指令。

或者换一种说法,我认为编译器在解释数组创建/初始化语法时可能遵循一些内置逻辑(派生自某个数学字段)。换句话说,编译器没有构建一个数组,因为它的开发人员给了它特定的指令,例如“当你看到词 newname of some type两对方括号 ([] []),然后按照这些分步说明进行操作,它将详细告诉您该怎么做”,但开发人员只是构建在一些与数学相关的逻辑中,并且从该编译器能够自行派生一个数组,而无需开发人员提供逐步说明。

顺便说一句——我确实了解锯齿状和矩形数组以及它们是如何初始化的等;)

【问题讨论】:

    标签: c# .net clr


    【解决方案1】:

    这是我关于其工作原理和设计注意事项的文章。希望这能回答您的问题。

    http://blogs.msdn.com/ericlippert/archive/2009/08/17/arrays-of-arrays.aspx

    尝试您的具体问题:

    如何评估数组类型声明“new int[10][]”?

    这不是类型声明。 “class C {}”是一个类型声明,因为它声明了一个新类型。你得到的是一个对象创建表达式。

    它是通过创建一个包含十个元素的新数组来评估的。每个元素都是一个变量,可以包含对整数数组的引用。这些变量中的每一个都被初始化为 null。

    它被评估为 (new int[10])[] 还是 (new int[10][])

    我不明白这个问题。前者是不合法的,后者只是括号中的再次表达。所以我想答案是它像后者一样被评估,因为两者是相同的,但我不禁认为我错过了问题的重点。

    但是假设编译器不会报错,那么编译器会根据这个语句创建什么样的数组类型呢?

    如果主教不限于在对角线上移动,那么女王的策略会有什么不同?

    问题没有提供足够的信息来回答问题。你必须说主教的新规则是什么,而不仅仅是解除什么限制。主教的新规则是什么?一旦我们知道了新规则,我们就可以分析游戏的变化。

    你没有提出规范说什么,只是提出了它不会说什么。这还不足以确定这个提议的表达式的语义。

    【讨论】:

    • @Eric Lippert:轻微的挑剔,但在“你所拥有的是一个对象初始化表达式”中。您的意思是“对象创建表达式”还是“数组创建表达式”,或者,超级迂腐,也许是“使用默认数组初始值设定项的数组创建表达式”?对不起。
    • @Eric Lippert: "它被评估为(new int[10])[] 还是(new int[10][]) [...] "前者是不合法的,后者只是括号中的表达式。" 注意两者之间有细微但重要的区别。第一个在new int[10] 周围有括号(因此(new int[10])[]),但在第二个没有这样的括号;第二个可以写为new int[10][]。前者确实是非法的,第二个只是重复他在问什么,所以我还是不明白他的问题。
    • @Jason:是的。那是一个错误。至于“有什么区别”的问题,我仍然不明白 OP 的区别。
    • 同意;我并不是要暗示澄清说明了他的问题。我想你在我编辑我的评论时回答了。
    • 我编辑了我的帖子,试图解释我的“意思”
    【解决方案2】:

    这是一个大小为 10 的数组,其成员类型为整数数组,也称为锯齿状数组。

    请参阅 MSDN 上 C# 教程的 this section(特别是锯齿状数组部分)。

    【讨论】:

    • 我了解锯齿数组,我只是好奇编译器如何评估数组类型声明
    【解决方案3】:

    我想我可以帮助回答你的问题。至少,我想我明白你不明白的地方,并且可以有说服力地喋喋不休。

    当编译器看到

    int[][] a = new int[10][];
    

    它的作用是创建一个长度为 10 的一维数组。该数组中的每个元素都能够持有对int[] 的引用。然后它将对这个长度为 10 的一维数组的引用分配给a。因此,如果你明白什么

    int[] a = new int[10];
    

    你现在应该能够理解什么了吗

    int[][] a = new int[10][];
    

    确实如此。前者保留了十个连续的插槽,可以容纳int。后者保留十个连续槽,可以保存对int[] 的引用。 (我们省略了额外的细节,例如Length 属性等。)所以,如果你想象一个幻想语法ArrayCreate(Type type, int length),前者是

    int[] a = ArrayCreate(typeof(int), 10);
    

    而后者是

    int[][] a = ArrayCreate(typeof(int[]), 10);
    

    现在,我不太明白您在标有“a)”和“b)”的两个问题中要问什么。也许您可以用这种奇妙的ArrayCreate 语法重新表述它们,我可以尝试回答它们?

    希望对你有帮助。

    【讨论】:

      【解决方案4】:

      它将为您提供一个宽度为 10 个整数值且深度不确定的向量。每个向量的深度将在 10 个索引中的每一个被实例化和填充时确定。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-11
        • 1970-01-01
        • 1970-01-01
        • 2017-06-06
        • 1970-01-01
        • 2015-02-20
        • 2015-10-07
        • 1970-01-01
        相关资源
        最近更新 更多