将过程分配给变量并用Pascal调用它们
我有一个显示菜单的小终端程序。我想要一个函数,它接受用户的输入和一个过程名数组,并能够调用用户选择的过程。我知道我可以在主程序中使用将过程分配给变量并用Pascal调用它们,pascal,Pascal,我有一个显示菜单的小终端程序。我想要一个函数,它接受用户的输入和一个过程名数组,并能够调用用户选择的过程。我知道我可以在主程序中使用if或case语句来实现这一点,但我想用上面的过程和几个其他菜单函数来制作一个单元,如果这是可能的,我可以让它调用任意过程。以下是我或多或少希望它如何工作的情况(我知道这是错误的,但你可以大致了解一下) 有没有办法做这样的事?提前谢谢你。我知道怎么做了。可以使用指向过程的指针,然后创建这些指针的数组,并将它们传递给我想要使用的过程。此外,出于某些原因,它似乎不适用于
if
或case
语句来实现这一点,但我想用上面的过程和几个其他菜单函数来制作一个单元,如果这是可能的,我可以让它调用任意过程。以下是我或多或少希望它如何工作的情况(我知道这是错误的,但你可以大致了解一下)
有没有办法做这样的事?提前谢谢你。我知道怎么做了。可以使用指向过程的指针,然后创建这些指针的数组,并将它们传递给我想要使用的过程。此外,出于某些原因,它似乎不适用于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\u-proc(0,proclist)
更改为call\u-proc(1,proclist)
,它将调用writeHello
。您的原始代码有一些错误,您的答案中没有引用
- 您有一个
过程
数组,但您正在调用writeln
,这些过程调用作为参数,就好像它们是函数
,而它们不是
readkey
是一个函数
,而不是过程
,因此其类型与数组的元素类型不匹配
- 将过程分配给数组需要使用
@
引用过程指针,而不是实际调用过程
- 不确定您正在使用什么编译器或选项,但
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.
您可以创建一个函数数组,返回与readkey
类型匹配的char
:
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.
FYItprocaray=过程数组代码>在这里的工作方式相同(Tprocptr=procedure
很好,但不是必需的)。这不是你最初的问题所在。您最初的问题是:(1)您缺少加载数组的过程引用前面的@
,以及(2)您在过程调用上调用writeln
,就好像它们是函数一样。您的注释不正确。此机制将与readkey
和clrsc
一起使用,但它们是不同的类型readkey
是一个返回char
的函数。所以您需要tprocaray=function:char的数组代码>。但是,这不适用于clrsc
,因为这是一个过程,并且与此数组的元素类型不匹配。不过,您可以在上面的代码中说proclist[1]=@clrsc代码>这应该行得通。你说得对。我不敢相信我为整数写了“int”,我是一个相当严重的疏忽:P.我也没有意识到readkey是一个函数,后来我意识到我确实不能写那些指针。感谢您的更正。请注意,Pascal标准没有程序类型,只有程序参数。过程类型是标准的扩展,因此不必提及特定的编译器,您可能会得到不同的答案。
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.