将过程分配给变量并在 Pascal 中调用它们

Assigning procedures to variables and calling them in Pascal

我有一个显示菜单的小终端程序。我想要一个函数,它接受用户的输入和一组过程名称,并能够调用用户选择的过程。我知道我可以在主程序中使用 ifcase 语句来做到这一点,但我想用上述过程和其他几个菜单功能制作一个单元,如果可能的话,我可以让它调用任意程序。这或多或少是我希望它的工作方式(我知道这是错误的,但这样你就有了一个大概的想法)。

program menu;
uses crt;

type procs = array [0..1] of procedure;

procedure call_procs(inp: int; procsy: procs);
    begin
      writeln(procsy[ord(inp)]); {And call it here.}
    end;

var procsx : procs;

begin
procsx[0] := readkey; {I would like to somehow store the procedure here.}
procsx[1] := clrscr;
call_procs(0, procsx); 
end.

有什么办法可以做这样的事情吗?提前谢谢你。

我知道怎么做了。可以使用指向过程的指针,然后创建这些指针的数组,并将它们传递给我想使用的过程。此外,出于某种原因,它似乎不适用于 Pascal 附带的函数(例如 readkey 或 clrscr)。对于此示例,可以这样做:

program menu;
type
  Tprocptr = procedure; {This creates a pointer to procedures.}
  Tprocarray = array of Tprocptr;

procedure writeHi;
begin
  writeln('Hi!');
end;

procedure writeHello;
begin
  writeln('Hello!');
end;

procedure call_proc(inp: integer; procsy: Tprocarray);
{This now calls functions like one would expect.}
begin
  procsy[ord(inp)];
end;

var 
  proclist : Tprocarray;

begin
  setlength(proclist, 2);
  proclist[0] := @writeHi; {The '@' creates a pointer to those procedures.}
  proclist[1] := @writeHello;
  call_proc(0, proclist);  
end.

这按预期工作,调用(在本例中)过程 writeHi,因此如果您 运行 这个程序,它将输出 Hi! 到终端。如果您将 call_proc(0,proclist) 更改为 call_proc(1, proclist),它将改为调用 writeHello

您的原始代码有一些错误,您的答案中没有引用这些错误。

  • 您有一个 procedure 的数组,但您调用 writeln 时将这些过程调用作为参数,就好像它们是 function,但它们不是。

  • readkeyfunction,不是 procedure,因此它的类型与数组的元素类型不匹配

  • 您将过程赋值给数组需要使用@来引用过程指针而不是实际调用过程

  • 不确定您使用的是什么编译器或选项,但是 int 不是标准的 Pascal 整数类型,integer 是。

作为一个小问题,因为你已经在使用数组的整数索引,所以你不需要使用 ord.

因此,为使其基本正常工作而对您的代码所做的最小改动是:

program menu;
uses crt;

type procs = array [0..1] of procedure;

procedure call_procs(inp: integer; procsy: procs);
begin
  procsy[inp]; { call the procedure here - removed 'ord' since it's superfluous }
end;

var procsx : procs;

begin
{  procsx[0] := readkey; {- 'readkey' is a function and won't work here }
  procsx[1] := @clrscr;
  call_procs(1, procsx); 
end.

您可以创建一个函数数组 return char 匹配 readkey 的类型:

program menu;
uses crt;

type procs = array [0..1] of function: char;

procedure call_procs(inp: integer; procsy: procs);
begin
  writeln(procsy[inp]);  { call the function; write out the returned char }
end;

function foo: char;
begin
  foo := 'X';
end;

var procsx : procs;

begin
  procsx[0] := @readkey;
  procsx[1] := @foo;
  call_procs(0, procsx);
  call_procs(1, procsx);
end.