从C 到Objectpascal的翻译检查更好

Translation check from C++ to ObjectPascal which is better

本文关键字:翻译 检查 更好 Objectpascal      更新时间:2023-10-16

我正在将一些C 代码转换为Objectpascal(首次),而C 对我来说仍然是新的。

C 标头文件看起来像这样:

class RenumFd {
public:
    RenumFd(int length);
    ~RenumFd();
    void CompFd(double *buff);
//...other public functions cut for space
private:
    void rmfd(int n, int isgn, double *a, int *ap, double *kw);
//...other private functions cut for space
    int _length;
    int *_ap;
    double *_kw;
}

我以这种方式翻译它们:

Type
 TRenumFD = class
 private
   _length: integer;
   _ap: Pinteger;
   _kw: Pdouble;
   procedure rmfd(n:integer; isgn:integer; var a:double; var ap:integer; var kw:double);
//... other procedures cut for space   
public
  constructor Create(const length:integer);
  destructor  Destroy(); override;
  procedure CompFd(var buff:double);
end;

我读到,在对象pascal中,应将用作C 参数的指针设置为VAR参数。是正确的,还是我应该坚持更字面的翻译(担心以后被咬伤)。

在C 构造函数中也有以下代码,我在一行中不确定。

RenumFd::RenumFd(int length) {
    _length = length;
    _ap = new int[2 + (1 << ((int)(log(2.0 + length) + 0.5) / 2))];
    _ap[0] = 0;  <-- is this setting the pointer to nil, or assigning 0?
    //...
}

我不确定是否应该在pascal中翻译该行,以填充第一个元素,或分配给nil:

_ap := AllocMem(2 + (1 shl (trunc(ln(2.0 + length) + 0.5) / 2))) * sizeOf(integer));
_ap := nil;

也许我努力猜测意图?

使用var或指针的决定确实取决于如何使用它,以及是否可以将其设置为nil。通常var更好,但是指针具有其用途。您没有提供足够的代码来显示最好的决定。

至于阵列分配,动态阵列AllocMem()

是更好的选择
type
  RenumFd = class
  public
    constructor Create(length: Integer);
    //...    
  private
    _ap: array of Integer;
    //...
  end;

constructor RenumFd.Create(length: Integer);
begin
  SetLength(_ap, 2 + (1 shl (Trunc(log(2.0) + 0.5) div 2)));
  _ap[0] := 0; // <-- assigns 0 to the first integer in the array
  //...
end;

通常,您的翻译质量很好。

我读到,应将用作C 参数的指针设置为VAR 对象pascal中的参数。是正确的,还是我应该坚持 更多字面翻译(担心以后被咬)。

我会说这是部分正确的。使用键入指针作为参数是通过参考实现传递参数的低级方法。它增加了通过NULL指针(nil)而不是实际变量参考的灵活性,从而有效地使参数可选。您应该检查您的代码是否有此类检查(if (kw) { *kw = ...; } /* writes to kw only if requested */)。如果无意制作指针参数(S)可选,则应通过参考声明(var或CC_7)坚持更高级别的

_ap[0] = 0;  <-- is this setting the pointer to nil, or assigning 0?

我不确定是否应该在pascal中翻译该行 用零或分配给零:

填充第一个元素
_ap := AllocMem(2 + (1 shl (trunc(log(2.0) + 0.5) / 2))) * sizeOf(integer));
_ap := nil;

也许我努力猜测意图?

您显然在可疑行中获得了隐式删除,因此将0写入_ap的第一个元素。覆盖指向最近的内存分配是不合逻辑的,不是吗?您的字面帕斯卡翻译应为: _ap^ := 0;

请注意,new运算符分配了超过1 int,因此您的PInteger类型还不够,您需要PIntegerArray。那就是:

type TIntegerArray = array[0..MaxInt div SizeOf(Integer)] of Integer;
type PIntegerArray = ^TIntegerArray;

_ap宣布为此类类型将为您节省大量的打字,并且仍然保持尽可能靠近C 原件。我不同意您需要的动态阵列是绝对不错的选择。

最后一个单词(次要):

constructor Create(const length:integer);

我没有目的是通过常数引用传递此整数,并且它实际上与原始C 代码不匹配。根本没有效果,但我会删除const