如何解决程序的循环引用问题?

8

我是 Delphi 编程领域的新手,我在控制台应用程序中调用一个过程中遇到了问题。

我的简单应用程序是一个物品清单,通过 Windows 上的 telnet 服务器运行。我使用一台旧的 ThinkPad 作为我的 ThinClient,在 Linux 上运行 telnet 客户端。

使用 Delphi XE,我遇到了一个先有鸡还是先有蛋的情况。

我得到了 addscreen 未声明的标识符...它已经在 mainscreen 下被声明了!!! 如果我将 addscreen 过程放在 mainscreen 过程之上,则在 addscreen 过程中对 mainscreen 的任何调用都会导致未声明的标识符 mainscreen 错误!

简单地说,如何使该过程在程序的任何位置都可以调用?

我尝试了接口和实现,但在控制台应用程序中无效!

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, windows, messages, Console in 'Console.pas';


procedure mainscreen;
var
  choice: string;
begin
  clrscr;
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln(' |                                     Inventory Management 0.1 ALPHA                                                         |');
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln('');
  writeln('');
  writeln('');
  writeln('');
  writeln('');
  writeln(' Make a choice: Add(a), Remove(r), Edit(e), Backup Database(bd), Mass Add(ma), Mass Remove(mr)');
  writeln('?:');
  readln(choice);

  if choice = 'a' then 
    addscreen
  else 
    mainscreen;
end;

procedure addscreen;
var
  choice: string;
begin
  clrscr;
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln(' |                                                     Add an Item                                                            |');
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln('');
  writeln('');
  writeln('');
  writeln(' Not yet ready!');
  writeln(' Press any key to return to the main menu...');
  readln(choice);

  mainscreen;
end;

begin
  mainscreen;
  textbackground(black);
  textcolor(lightgray);
  ExitProcess(0);
end.

非常感谢您!

你最好将“mainscreen”代码移动到“main”程序中,并将更多语句移动到“repeat”循环中。 - No'am Newman
1个回答

13
编译器从上到下依次处理文件。在需要处理对addscreen的调用时,您还没有声明addscreen

由于存在循环引用(addscreen调用mainscreen,反之亦然),因此需要使用所谓的前向引用来打破循环引用。在mainscreen之前添加以下行:

procedure addscreen; forward;

所以代码的组织应该像这样:

procedure addscreen; forward;

procedure mainscreen;
begin
  ...
end;

procedure addscreen;
begin
  ...
end;
如果您没有循环引用,那么您可以简单地重新排列程序,使得 addscreenmainscreen 之前声明。

3
谢谢!在 Google 上搜索了很多次都没有结果,最后在 Stack Overflow 上找到了正确的答案!非常感谢! - ELCouz
1
下次当你搜索这个问题时,你会发现谷歌在stackoverflow上列出了你的问题和David的答案。 - lkessler
我不知道 forward 指令。我认为它在没有它的情况下也可以工作。它是从什么时候开始出现的? - jpfollenius
@Smasher 如果A调用B,而B又调用A,则需要使用前向指令。也许您正在考虑类的方法,其中类声明提供了前向声明。自Wirth发明以来,Pascal中一直存在“forward”关键字。 - David Heffernan
当然,你是对的。我想到了类声明。在这种情况下它是否适用?确实更易读。 - jpfollenius
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接