Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.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
将过程分配给变量并用Pascal调用它们_Pascal - Fatal编程技术网

将过程分配给变量并用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.

FYI
tprocaray=过程数组在这里的工作方式相同(
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.