6
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;          

加、乘、减、除都是过程。如果我把它放在主程序中,它会正常工作,但是当我把它作为一个过程本身时,我得到错误undeclared identifier。我在很多网站上都看过这样的例子,但我找不到。

如何让加法、乘法、减法、除法从这个内部进入他们的程序?

4

3 回答 3

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 通过使用 *forward 声明支持 A 调用 B 和 B 调用 A 的协同例程。例如:

procedure B; forward;

procedure A;
begin
  B;
end;

procedure B;
begin
  A;
end;

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

但是,很少需要前向声明,应尽可能避免,因为它们会增加复杂性。总是可以通过简单地重新排序您的声明来找到解决方案。

最后,声明在使用之前发生的排序约束在 Brian Kernighan 的著名文章“为什么 Pascal 不是我最喜欢的编程语言”中明确提到。

于 2011-03-19T16:31:43.703 回答
6

我看到您已经标记了您的问题[delphi]以及[pascal],所以我猜您实际上是在编写 Delphi 代码。然后你有更多的选择,除了关心程序的顺序和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在这个单元中使用(例如,inside DoThisDoThat)。此外,这个常数BUFFER_SIZE在这个单元之外也是不可见的。

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

这种方法的一个好处是它至少可以解决您的问题。如果add、和过程对其他单元可见multiply,则应在节中声明它们。但是,当涉及到您的过程时,编译器确实知道它们,因此即使它们在该部分内的过程下方定义(实现),您也可以使用调用这些。但是,另一方面,如果让其他单位使用这些程序完全没有意义,则不应在该部分中声明它们,您需要按照 David 的建议进行操作。如果您的项目中根本没有正常单位,这也适用,也就是说,如果您只有subtractdivideinterfacequestiontypequestiontypeimplementationinterfaceprogram文件,它没有分成interfaceimplementation部分。

于 2011-03-19T17:55:30.490 回答
2

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

于 2011-03-19T17:22:19.223 回答