为什么旧的BASIC(也许还有其他语言)使用行号作为源代码的一部分?
我的意思是,(尝试)解决了什么问题?
为什么旧的BASIC(也许还有其他语言)使用行号作为源代码的一部分?
我的意思是,(尝试)解决了什么问题?
Answers:
必须将BASIC与它的当代语言结合起来:早期的fortran,cobol和Assembly。
回到我尝试使用 没有标签的6502程序集时,这意味着当您发现需要在紧密打包的代码中间添加一条指令(我后来添加了NOP)时,您需要遍历并重做所有跳转地址。这很耗时。
Fortran是早于BASIC的基于行号的系统。在Fortran中,第1-5列是用于分支目标的行号。Fortran的关键之处在于,编译器往往比BASIC解释器更智能,添加一些指令仅是对一些卡进行打孔并将它们放置在正确的位置。
另一方面,BASIC必须保留其所有指令的顺序。“延续上一行”的概念不多。相反,在Applesoft BASIC(我熟悉并可以找到信息的广泛使用的方言之一)中,内存中的每一行都表示为:
NN NN TT TT AA BB CC DD .. .. 00
下一行(NN NN
)的地址有两个字节。该行的行号(TT TT
),然后是令牌列表(AA BB CC DD .. ..
),后跟行标记(00
),两个字节。(摘自《 Inside the Apple》第84-88页// e)
查看该内存表示形式时要意识到的重要一点是,这些行可以无序存储在内存中。内存的结构是链表的结构,在结构中带有“下一行”指针。这使得在两行之间添加新行变得容易,但是您必须对每行进行编号才能使其正常工作。
很多时候使用BASIC,您实际上是在 BASIC本身中工作。特别是,给定的字符串可以是行号和BASIC指令,也可以是基本解释器的命令RUN
或LIST
。这样可以轻松地将代码与命令区分开-所有代码均以数字开头。
这两条信息确定了为什么要使用数字-您可以在16位中获得大量信息。基于字符串的标签将占用更多空间,并且更难订购。数字易于使用,易于理解且易于表示。
后来您一直不在解释器中的BASIC方言可以消除编号的每一行,而只需要对作为分支目标的行进行编号。实际上,是标签。
] PRINT "FOO"
由BASIC解释器立即运行。这是一个声明。如果你想稍后再运行它,你会怎么做] 10 PRINT "FOO"
,然后] RUN
。在AppleSoft BASIC环境中,每个BASIC语句都可以立即运行或延迟运行-DOS提供的命令很少,这些命令不是有效的BASIC语句。现在的语句和以后的语句之间的区别是行号。您也可以通过重新输入相应的行号来修改延迟的语句。您也可以在一行上放置多个语句::
在早期的微型计算机上,编辑是基于行的。您不能随便在源代码中自由移动并进行编辑。屏幕底部只有一行,您可以在其中键入命令并输入代码。屏幕的其余部分是只读代码列表和命令输出。如果要编辑,请在程序中说第90行,您编写了“ EDIT 90
”,然后行的内容90
输入了单行编辑缓冲区。编辑完该行后,请按Enter键,并且程序清单已更新。因此,您需要行号才能编辑程序。
当代码编辑器变得更加高级并允许您在代码清单中移动光标时,您不再需要行号。
如果您正在考虑80年代的8位家用微型计算机的BASIC方言,那么这些计算机就没有文本编辑器(除非您购买了某些文字处理器应用程序)。就像今天进行编程时一样,无法“编辑器中打开”整个BASIC程序源代码。程序员甚至根本不会将程序视为源代码文件或文本。
因此,假设您有一个简单的程序,头上没有行号:
FOR I=1 TO 42
PRINT I
NEXT I
您启动计算机。您有一个提示“就绪”或类似的提示,并且光标位于下一行。这很像当今使用不同脚本语言的REPL环境,尽管并不是严格地基于行,而是更像基于屏幕。因此,它与今天的REPL不太相似,但是接近。
现在,如果您开始进入程序,则第一行之后可能会出现错误,因为BASIC解释器试图立即执行(并忘记)它,而没有NEXT结束循环就没有意义。这不是文本编辑器,您不能在其中编辑文本,这是您向计算机发出命令的地方!
所以,您需要说些什么,这是程序行,存储它!您可能有一个特殊的命令,或者只是一个符号,告诉您,这是程序行,请存储它。让我们想象一下:
#FOR I=1 TO 42
#PRINT I
#NEXT I
好的,现在我们虚构的BASIC解释器存储了程序,您可以运行它。但是现在您要编辑PRINT行。你怎么做呢?您不在文本编辑器中,不能仅将光标移至该行并进行编辑。或者您想要添加另一行,例如LET COUNT=COUNT+1
在循环中。您如何指示应该在哪里插入新行?
行号以一种非常简单的方式解决了这个问题,即使是很笨拙的方式。如果您输入的程序行已经存在一个数字,则旧行将被替换。现在,基于屏幕的REPL环境变得很有用,因为您只需将光标移至屏幕上的程序列表,在屏幕上编辑该行,然后按Enter进行存储即可。好像您正在编辑该行,实际上是在屏幕上编辑文本,然后用屏幕上的新行替换整个行。此外,如果您在中间插入未使用的数字,则插入新行变得容易。展示:
10 FOR I=1 TO 42
20 PRINT I
30 NEXT I
重新输入第20行的更改并添加新行后,可能是
5 LET COUNT=0
10 FOR I=1 TO 42
20 PRINT "Index", I
25 LET COUNT=COUNT+1
30 NEXT I
能够将行号用作语言构造(至少作为GOTO
AND GOSUB
命令的目标)是有好处的(或受诅咒的,因为它使著名的BASIC意大利面条代码成为可能)。可以用标签代替,但是在BASIC解释器中使用行号要容易得多,这在80年代典型的8位家用计算机中仍然是绝对的优势。
更重要的是,从用户体验的角度来看,行号确实是一个令人惊讶的简单而完整的代码编辑界面。只需键入以数字开头的行即可插入新代码。使用LIST 100-200
显示线100-200。要编辑一行,请在屏幕上列出该行,在屏幕上编辑文本,然后重新输入行。要删除一行,请将其编辑为空,即只需给行号加上任何空格。一段描述了这一点。比较一下尝试描述使用旧文本编辑器(如DOS的edlin或Unix的ed或ex)的情况:您需要一个段落(仅略微夸张)来说明用户意外启动时如何退出它们!
其他答案解释了行号是如何变成的。我试图在这里介绍行号为什么能生存如此长的时间,如何继续解决现实世界的问题:它们提供了一种无需真正编辑器即可以非常简单的方式进行实际编程的方法。一旦适当,易于使用的全屏文本编辑器成为编辑代码的主流方式,这不仅消除了硬件限制,而且克服了人们适应新事物的惯性,然后基于行号的BASIC方言很快就从使用中消失了,因为他们解决的核心可用性问题不再是问题。
在开发Basic的时代和时代,最好的I / O设备是电传打字机。通过打印(在纸上)整个程序的列表或其中有趣的部分,然后键入带有行号的替换行来完成程序的编辑。
这就是默认行号加10的原因,因此现有行之间会有未使用的数字。
ren
'命令,以进行重新编号。一个典型的调用是ren 10, 10
(重新编号开始十,十递增-默认行为,如果一个刚键入ren
该goto
和gosub
和then (linenumber)
。命令会自动更新,但是,这绝对不是最早的基本可用,但IIRC,在苹果公司提供。整数基础,Applesoft FP基础,TI基础/扩展基础,MS基础/ GW基础等
“行号”表示一些不同的内容。
首先,请记住,“线条”的概念并没有永远存在。这个时代的许多编程语言都使用打孔卡,并且具有序列号(通常在卡的最后几列中)可以帮助您以正确的顺序恢复卡组(如果您放下了卡组),或者读卡器中发生了一些糟糕的事情。有机器自动执行此操作。
用作GOTO
语句目标的行号是一个完全不同的概念。在FORTRAN IV中,它们是可选的,位于语句之前(在1-5列中)。除了比自由格式的标签更易于实现之外,还有计算和分配的GOTO的概念,它使您可以跳转到任意行号。这是大多数现代编程语言所没有的(尽管switch
语句很接近),但这是汇编程序员熟悉的技巧。
BASIC是从FORTRAN派生的,其意图是更易于实现和理解,因此,强制每个“行”都具有行号(既用于排序又作为GOTO
/ GOSUB
语句的目标)是出于这个原因而做出的设计决策。
goto array_of_labels[some_computation()];
GOTO
(或ASSIGN
)与原又名算术又名三通IF
,以及(很少使用)的交替返回CALL
,和排序的-目标(可以说是分隔符)DO
,和FORMAT
语句。在其他陈述中,它们是可选的。
GOTO 1000+N*100
仿真switch
语句。
我开始使用COBOL编程,该编程使用每行1-6列中的行号。因为在1970年代没有IDE,所以一切都是通过打孔卡完成的,并且使用行号来标识要替换原始源中的哪些行以及添加哪些新行。我们过去通常将行号增加100,以便给我们增加更多行的空间。
在线路终端时代,BASIC的出现要晚于FORTRAN。它具有一个read-exe-print-loop环境,它比一副纸牌更具交互性。
我学会了用BASIC在一行包含24个字符的显示器上编程。行号是一种自然的方式,它可以指定要移到的行,无论是编辑一条还是插入其他一条。
我真的无法想象你还会怎么做。