Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何做C++;Delphi中的参数数组指针算法 在C++中,可以发送允许数组上指针运算的参数。我需要能够在Delphi7项目中做到这一点。我试着这样做,但接收程序是咳嗽。如果数组指针递增,c^[0]不应该位于新的递增位置吗_C++_Arrays_Delphi_Pointers_Delphi 7 - Fatal编程技术网

如何做C++;Delphi中的参数数组指针算法 在C++中,可以发送允许数组上指针运算的参数。我需要能够在Delphi7项目中做到这一点。我试着这样做,但接收程序是咳嗽。如果数组指针递增,c^[0]不应该位于新的递增位置吗

如何做C++;Delphi中的参数数组指针算法 在C++中,可以发送允许数组上指针运算的参数。我需要能够在Delphi7项目中做到这一点。我试着这样做,但接收程序是咳嗽。如果数组指针递增,c^[0]不应该位于新的递增位置吗,c++,arrays,delphi,pointers,delphi-7,C++,Arrays,Delphi,Pointers,Delphi 7,第一个过程调用makect(),但首先通过递增将指针移动到数组中较高的内存位置。但是,当设置为数组指针位置0时,第二个过程不喜欢它。(当然可能还有其他问题,但我想知道我是否做得对) 为清晰起见,此处列出了类型 type Pflt = ^flt; flt = double; Pflt_arr = ^flt_arr; flt_arr = array of flt; Pint_arr = ^int_arr; int_arr = array of integer; 建造师

第一个过程调用makect(),但首先通过递增将指针移动到数组中较高的内存位置。但是,当设置为数组指针位置0时,第二个过程不喜欢它。(当然可能还有其他问题,但我想知道我是否做得对)

为清晰起见,此处列出了类型

type
  Pflt = ^flt;
  flt = double;

  Pflt_arr = ^flt_arr;
  flt_arr = array of flt;

  Pint_arr = ^int_arr;
  int_arr = array of integer;
建造师

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  _ip[0] := 0;
  SetLength(_w, length shr 1);
end;


procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, @_ip, @_w);
end;
呼叫程序

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
xi: flt;
begin
 nw := ip^[0];
 nc := ip^[1];
 if n > (nc shl 2) then
 begin
  nc := n shr 2;
  inc(w, nw);       <--attempt at pointer arithmetic
  makect(nc, ip, w); <-- C++ version is makect(nc, ip, w + nw);
 end;
end;
procedure TRefT.rdft(n:integer;isgn:integer;a:Pflt_arr;ip:Pint_arr;w:Pflt_arr);
var nw,nc:整数;
十一:外语教学;;
开始
nw:=ip^[0];
nc:=ip^[1];
如果n>(nc shl 2),则
开始
nc:=n shr 2;

公司(西,西北), 你的代码不正确。你有一个额外的,错误的,间接的层次。这里需要的是指向
Double
的静态数组的指针,而不是指向
Double
的动态数组的指针

请记住,动态数组是作为指向数组第一个元素的指针实现的。因此,就间接性而言,您的类型相当于指向标量的指针

一种方法是像这样声明类型

type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;
并确保已为此代码禁用更改检查

这将允许您编写:

a^[i]
inc(Pflt(a), n);
a
Pflt\u数组类型时

更重要的是,如果你写:

inc(a, n);
然后它将地址
a
增加
n*sizeof(a^)
这是
n*sizeof(Tflt_数组)
这是
n*sizeof(flt)*长度(a^))
这是
n*sizeof(flt)
这正是您想要的

当您提供一个常量表达式作为索引时,这种情况就会发生。根据这一行:

nc := ip^[1];
在这里,编译器将反对
1
不在范围
0..0
内。所以你不能两全其美

在这种情况下,您似乎需要破解
ip
的前两个元素。你可以这样做:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;
然后写:

nc := Phuge_int_arr(ip)^[1];
感觉有点乱


另一种方法是编写如下类型:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;
这适用于所有索引方案,并允许您保持范围检查处于启用状态。但它使指针递增变得更加困难。现在你必须写:

a^[i]
inc(Pflt(a), n);
总的来说,后一种方法可能是两害中较小的一害


声明实际存储的代码仍应使用动态数组、
SetLength
等。当您需要
Pflt\u数组
Pint\u数组
强制转换动态数组时:

Pflt_array(dyn_array)
这是因为动态数组被实现为指向数组第一个元素的指针


对于
0..0
变量,您的代码如下所示:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;

或者使用
0..(MaxInt div sizeof(scalar))-1的替代方法如下所示:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;
你挑吧


FWIW为了清晰起见,您可以在移植此代码时利用此机会将
shl2
shr2
操作更改为算术操作

您可能不知道的一个选项是根本不翻译。将原始.c文件编译成对象,并使用
$link
静态链接它们


最后一点意见是,很遗憾您一直使用如此旧版本的Delphi。现代版本有
$POINTERMATH
编译器选项。这允许C风格的指针算法和标量变量的普通指针索引。对于这样的移植任务来说,这是一个巨大的好处

您的代码不正确。你有一个额外的,错误的,间接的层次。这里需要的是指向
Double
的静态数组的指针,而不是指向
Double
的动态数组的指针

请记住,动态数组是作为指向数组第一个元素的指针实现的。因此,就间接性而言,您的类型相当于指向标量的指针

一种方法是像这样声明类型

type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;
并确保已为此代码禁用更改检查

这将允许您编写:

a^[i]
inc(Pflt(a), n);
a
Pflt\u数组类型时

更重要的是,如果你写:

inc(a, n);
然后它将地址
a
增加
n*sizeof(a^)
这是
n*sizeof(Tflt_数组)
这是
n*sizeof(flt)*长度(a^))
这是
n*sizeof(flt)
这正是您想要的

当您提供一个常量表达式作为索引时,这种情况就会发生。根据这一行:

nc := ip^[1];
在这里,编译器将反对
1
不在范围
0..0
内。所以你不能两全其美

在这种情况下,您似乎需要破解
ip
的前两个元素。你可以这样做:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;
然后写:

nc := Phuge_int_arr(ip)^[1];
感觉有点乱


另一种方法是编写如下类型:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;
这适用于所有索引方案,并允许您保持范围检查处于启用状态。但它使指针递增变得更加困难。现在你必须写:

a^[i]
inc(Pflt(a), n);
总的来说,后一种方法可能是两害中较小的一害


声明实际存储的代码仍应使用动态数组、
SetLength
等。当您需要
Pflt\u数组
Pint\u数组
强制转换动态数组时:

Pflt_array(dyn_array)
这是因为动态数组被实现为指向数组第一个元素的指针


对于
0..0
变量,您的代码如下所示:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;

或者使用
0..(MaxInt div sizeof(scalar))-1的替代方法如下所示:

type
  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;
type
  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..0] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..0] of Integer;

  Phuge_int_arr = ^Thuge_int_arr; 
  Thuge_int_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := Phuge_int_arr(ip)^[0];
  nc := Phuge_int_arr(ip)^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(w, nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  Phuge_int_arr(ip)^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
type
  Pflt = ^flt;
  flt = Double;

  Pflt_arr = ^Tflt_arr;
  Tflt_arr = array [0..(MaxInt div sizeof(flt))-1] of flt;

  Pint_arr = ^Tint_arr;
  Tint_arr = array [0..(MaxInt div sizeof(Integer))-1] of Integer;

....

constructor TRefT.Create(const length:integer);
begin
  len := length;
  SetLength(_ip, 2 + (1 shl trunc(ln(length / 4.0) / ln(2.0) + 0.5) shr 1) );
  SetLength(_w, length shr 1);
end;

procedure TRefT.CF(buff: pflt_arr);
begin
  rdft(len, 1, buff, Pint_arr(_ip), Pflt_arr(_w));
end;

procedure TRefT.rdft(n:integer; isgn:integer; a:Pflt_arr; ip:Pint_arr; w:Pflt_arr);
var nw, nc: integer;
    xi: flt;
begin
  nw := ip^[0];
  nc := ip^[1];
  if n > (nc shl 2) then
  begin
    nc := n shr 2;
    inc(Pflt(w), nw);
    makect(nc, ip, w);
  end;
end;

procedure TRefT.makect(nc:integer; ip:Pint_arr; c:Pflt_arr);
var j, nch: integer;
    delta: flt;
begin
  ip^[1] := nc;
  if nc > 1 then
  begin
    nch := nc shr 1;
    delta := arctan(1.0) / nch;
    c^[0] := cos(delta * nch);
    c^[nch] := 0.5 * c^[0];
    for j := 1 to nch do
    begin
      c^[j] := 0.5 * cos(delta * j);
      c^[nc - j] := 0.5 * sin(delta * j);
    end;
  end;
end;
Type
 TRefT = class
 private
   len : Integer;
   _ip : array of integer;
   _w  : array of double;
 public
   Constructor Create(const length : integer);
   procedure CF(const buff : array of double);  // Or var
   procedure rdft(       n    : integer;
                         isgn : integer;
                   const a    : array of double;  // Or var
                     var ip   : array of integer;
                     var w    : array of double);
   procedure makect(     nc : integer;
                         nw : integer; // c array index offset
                     var ip : array of integer;
                     var c  : array of double);
 end;
你挑吧


FWIW在移植此代码时,您可以借此机会更改
SHL2