如何在Pascal中的另一个过程中调用过程

时间:2011-03-19 16:25:54

标签: delphi pascal procedure

procedure questiontype;  
 begin  
  writeln ('Enter the type of question you would like...');  
  writeln ('1. Add');  
  writeln ('2. Multiply');  
  writeln ('3. Subtraction');  
  writeln ('4. Division');  
  readln (typeofquestion);  
   case typeofquestion of
    1: add;
    2: multiply;
    3: subraction;
    4: division   
else writeln ('Choose again'); 
end;
end;          

加法,乘法,减法和除法都是程序。如果我把它放在主程序中,它会正常工作,但当我把它作为一个程序本身,我得到错误未声明的标识符。我在许多网站上看过一个这样的例子,但我找不到任何网站。

如何将加法,乘法,减法,除法从这个内部转到他们的程序?

3 个答案:

答案 0 :(得分:14)

您必须在调用它们的例程之前声明过程。虽然您没有展示如何定义其他例程,但我推断它们是在您显示的例程之后声明的。

因此,您只需重新排序代码,以便在调用它们的过程之前定义加,乘,减法和除法。

所以这会奏效:

procedure add;
begin
  //do something;
end;

procedure questiontype;  
begin  
  add;  
end;

但这不会编译:

procedure questiontype;  
begin  
  add;  
end;

procedure add;
begin
  //do something;
end;

Pascal及其变体在一次传递中编译,如果编译器在提及它的时候不知道例程,则无法继续。

Pascal支持协同例程,其中A通过使用* forward声明来调用B和B调用A.例如:

procedure B; forward;

procedure A;
begin
  B;
end;

procedure B;
begin
  A;
end;

当然这是一个写入的无限循环,它将以堆栈溢出终止(多么合适!)但是当然有必要的实例。

但是,很少需要前向声明,如果可能的话应该避免使用,因为它们会增加复杂性。只需重新订购您的声明即可找到解决方案。

最后一点,Brian Kernighan着名文章Why Pascal is Not My Favorite Programming Language中明确提到了声明在使用前发生的排序约束。

答案 1 :(得分:6)

我发现你已经标记了你的问题[delphi]以及[pascal],所以我猜你实际上在编写Delphi代码。除了关心程序的顺序和David讨论的forward指令之外,你还有更多的选择。

大多数情况下,Delphi项目(GUI 控制台)被划分为“单位”。一个典型的单位看起来像这样:

unit MyUnit;

interface

const
  RANDOM_NUMBER = 17;

var
  PrintExtraNiceMessage: boolean;

procedure DoThis;
procedure DoThat;

implementation

const
  BUFFER_SIZE = 256;

procedure InitSomething;
begin
  // TODO: do some internal work...
end;

procedure DoThis;
begin
  // TODO: do something
end;

procedure DoThat;
begin
  // TODO: do something else
end;

您会注意到该单元分为两部分:interface部分和implementation部分。 interface部分仅包含声明(函数,过程,类型,常量和变量);此处声明的函数和过程在implementation部分中定义(即实现)。请注意,implementation部分中定义的函数和过程可能在interface部分中没有声明。

宏伟的想法是interface部分的内容对于程序中的所有其他单元是可见的,而implementation部分的内容仅在此单元内可见。因此,您的计划中的任何其他单元都可以使用RANDOM_NUMBER常量,PrintExtraNiceMessage变量以及两个程序DoThisDoThat。但是,您只能在此单元中使用InitFunction(例如, DoThisDoThat内)。此外,常数BUFFER_SIZE在此单位之外也不可见。

这是一种非常优雅的方法。 interface部分描述了如何在其他单元中使用此单元(例如,有哪些功能以及如何使用它们),并且实现细节在implementation部分中“隐藏”。

这种方法的一个好处是它至少可能解决了你的问题。 如果 addmultiplysubtractdivide程序应该对其他单位可见,那么它们应该在{{{ 1}}部分。但是,当它到interface过程时,编译器确实知道它们,因此即使它们在questiontype过程中questiontype过程下定义(实现),也可以使用它们。 1}}部分。但是,另一方面,如果让其他单位使用这些程序毫无意义,那么就不应该在implementation部分声明它们,你需要按照David的建议去做。如果您的项目中根本没有正常单位,也就是说,如果您只有interface文件,而该文件没有划分为programinterface部分,则这也适用。

答案 2 :(得分:2)

请注意,OP的示例中有一个仅适用于最后一个“if”的else。据推测,如果他们输入1,2或3,相应的程序将触发,返回,然后他们会看到“再次选择”。如果他们进入4,他们不会。这可以通过Case或级联if..else得到很好的服务,如果结构中最后的else只是在“当其他所有方法都失败时”触发,这就像OP所期望的那样。