将过程分配给变量并在 Pascal 中调用它们
Assigning procedures to variables and calling them in Pascal
我有一个显示菜单的小终端程序。我想要一个函数,它接受用户的输入和一组过程名称,并能够调用用户选择的过程。我知道我可以在主程序中使用 if
或 case
语句来做到这一点,但我想用上述过程和其他几个菜单功能制作一个单元,如果可能的话,我可以让它调用任意程序。这或多或少是我希望它的工作方式(我知道这是错误的,但这样你就有了一个大概的想法)。
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
,但它们不是。
readkey
是 function
,不是 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.
我有一个显示菜单的小终端程序。我想要一个函数,它接受用户的输入和一组过程名称,并能够调用用户选择的过程。我知道我可以在主程序中使用 if
或 case
语句来做到这一点,但我想用上述过程和其他几个菜单功能制作一个单元,如果可能的话,我可以让它调用任意程序。这或多或少是我希望它的工作方式(我知道这是错误的,但这样你就有了一个大概的想法)。
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
,但它们不是。readkey
是function
,不是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.