从C 到Objectpascal的翻译检查更好
Translation check from C++ to ObjectPascal which is better
我正在将一些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
。
- valgrind-hellgrind与泄漏检查的结果不同
- C++模板来检查友元函数的存在
- 检查输入是否不是整数或数字
- 试图让变量检查数组中的某些内容
- 不同翻译单元中不可重载的非内联函数定义
- 检查值是否在集合p1和p2中,但不在p3中
- C++概念:如何使用'concept'检查模板化结构的属性?
- 概念TS检查忽略私有访问修饰符
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何在C++中检查2D数组中负值的输入验证
- C++:正在检查LinkedList中的回文-递归方法-错误
- 使用for循环检查数组中的重复项
- 如何检查一个c++字符串中有多少相同的字符/数字
- 检查不带转换的扫描格式
- 如何检查线程是否锁定
- 清除前检查矢量
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- C++LDAP检查用户是否是特定组的成员
- 从C 到Objectpascal的翻译检查更好