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;
加法,乘法,减法和除法都是程序。如果我把它放在主程序中,它会正常工作,但当我把它作为一个程序本身,我得到错误未声明的标识符。我在许多网站上看过一个这样的例子,但我找不到任何网站。
如何将加法,乘法,减法,除法从这个内部转到他们的程序?
答案 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
变量以及两个程序DoThis
和DoThat
。但是,您只能在此单元中使用InitFunction
(例如,在 DoThis
或DoThat
内)。此外,常数BUFFER_SIZE
在此单位之外也不可见。
这是一种非常优雅的方法。 interface
部分描述了如何在其他单元中使用此单元(例如,有哪些功能以及如何使用它们),并且实现细节在implementation
部分中“隐藏”。
这种方法的一个好处是它至少可能解决了你的问题。 如果 add
,multiply
,subtract
和divide
程序应该对其他单位可见,那么它们应该在{{{ 1}}部分。但是,当它到interface
过程时,编译器确实知道它们,因此即使它们在questiontype
过程中questiontype
过程下定义(实现),也可以使用它们。 1}}部分。但是,另一方面,如果让其他单位使用这些程序毫无意义,那么就不应该在implementation
部分声明它们,你需要按照David的建议去做。如果您的项目中根本没有正常单位,也就是说,如果您只有interface
文件,而该文件没有划分为program
和interface
部分,则这也适用。
答案 2 :(得分:2)
请注意,OP的示例中有一个仅适用于最后一个“if”的else。据推测,如果他们输入1,2或3,相应的程序将触发,返回,然后他们会看到“再次选择”。如果他们进入4,他们不会。这可以通过Case或级联if..else得到很好的服务,如果结构中最后的else只是在“当其他所有方法都失败时”触发,这就像OP所期望的那样。