【问题标题】:Arrays as result type and input for functions数组作为函数的结果类型和输入
【发布时间】:2010-10-01 10:20:56
【问题描述】:

在delphi7中我有一个函数,我需要返回一个数组作为结果类型b

"函数创建框(key:tkey):array[0..255] of byte;"这是不允许的,它期望“预期的标识符,但找到的数组”是错误抛出。如果我声明一个记录类型的数组似乎可以正常工作,但为一个函数执行此操作似乎毫无意义。

【问题讨论】:

    标签: delphi arrays function


    【解决方案1】:

    问题是不允许在函数声明中创建新类型。但这就是您将返回类型指定为array[0..255] of Byte 时所做的事情。相反,声明一个命名类型,然后将其用作返回类型:

    type
      TSBox = array[0..255] of Byte;
    
    function CreateSBox(const Key: TKey): TSBox;
    

    【讨论】:

    • 请注意,使用这种类型作为函数结果很慢,因为它会将内容从堆栈复制到结果值。您应该编写程序 CreateSBox(const Key: TKey; var Result: TSBox);为了更快的执行。如果数组大小很大,它会有所作为。
    • @A.Bouchez:不在 Delphi 中(但可能在 FPC 中)。在 Delphi 动态类型(例如 String/dyn-arrays/interfaces)中,作为 Result 的自动传递类似于 CreateSBox(const Key: TKey; var Result: TSBox)。请参阅示例代码copypastecode.com/60195,但由于这种优化,编译器中存在一个长期存在的错误(不是)生成警告,请参阅:qc.embarcadero.com/wc/qcmain.aspx?d=894(它不仅与函数 Result as String 相关,还与接口、dyn-arrays 相关, 记录)
    • @kibab:我说的不是引用计数类型,而是记录或静态数组(比如这个 TSBox = array[0..255] of Byte)。在这种情况下,内容是从堆栈中复制的,而不是作为引用传递。
    • 似乎对于像这个 TSBox 这样的静态数组(甚至记录)是相同的(至少在 D2009 下) - 没有副本,只是指向该变量的指针。你能试试这个吗?在简单的测试中我可能会犯一些错误。在 CPU 视图中,我只看到简单的 MOV,然后是 CALL。
    【解决方案2】:

    这有一个微妙的原因,在 Pascal 中,无论它们的声明多么相同,两个数组类型声明都不是同一个“类型”,因此不兼容赋值。如果你写:

    var
      A: array[1..10] of Integer;
      B: array[1..10] of Integer;
    

    A 和 B 是不同的类型。如果你写

    A := B;
    

    代码不会编译,A和B是不同的类型。

    因此,如果你写

    var
      A: array[1..10] of Integer;
    ...
    function Foo(...): array[1..10] of Integer;
    

    您实际上是在为函数结果声明一个类型 - 该类型将毫无用处,因为无论其声明方式如何,您都无法将其分配给 A 或任何数组,例如:

      A := Foo(...);
    

    即使编译器允许您以这种方式声明函数,也不会起作用。

    因此获得有用的函数结果类型的唯一方法是使用已声明的类型。只有开数组是此规则的例外,但它们只能用作函数参数,不能用作结果。

    【讨论】:

      【解决方案3】:

      好的 type TSBox = array of Byte 可以正常工作,但是在 2 个或更多单元中使用这种新类型可能会很棘手。因为你会收到一条错误消息“不兼容的类型”。 这种情况有部分解决方案。你可以用这个符号通知编译器哪个单元具有该类型:unit.type; 例子: 想象一下,我有一个名为 Web 的单元,我在其中声明类型 TDownload。我可以做这样的事情: var fileUrl : Web.TDownload; 在这种情况下,编译器将理解您使用相同的类型。 但是,这就是我对你们所有人的问题:如果你们不想将该单元放在使用条款中以用于任何用途 - 循环引用、便便良好做法等。我能做些什么来避免这个问题?

      【讨论】:

      • 使用过程 CreateSBox(const Key: TKey; var Result: TSBox) 正如我在上面的评论中所写。 var 参数将检查 EXACT 类型匹配。而且它会跑得更快。
      猜你喜欢
      • 2013-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多