为什么BASIC使用行号?


95

为什么旧的BASIC(也许还有其他语言)使用行号作为源代码的一部分?

我的意思是,(尝试)解决了什么问题?


27
如果您已经进行了认真的研究工作,请不要将其相关信息埋在评论中,而应相应地编辑您的问题。此外,谷歌把我直接在这里:stackoverflow.com/questions/541421/...这里stackoverflow.com/questions/2435488/...
布朗博士

13
我投票关闭这个问题为离题,因为答案已经在stackoverflow上
安德列斯·F

6
Applesoft BASIC是我学习的第一门编程语言。我记得曾经听说Pascal没有行号,但是这样说:“但是我如何在没有行号的情况下进行GOTO?这应该如何工作?”
Jens Schauder

14
有趣的是,我上次检查时,我们正在判断问题是否是基于其内容而不是其他站点的内容(并且可能是在那里的答案)所基于的主题。
MatthewRock

Answers:


130

必须将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指令,也可以是基本解释器的命令RUNLIST。这样可以轻松地将代码与命令区分开-所有代码均以数字开头。

这两条信息确定了为什么要使用数字-您可以在16位中获得大量信息。基于字符串的标签将占用更多空间,并且更难订购。数字易于使用,易于理解且易于表示。

后来您一直不在解释器的BASIC方言可以消除编号的每一行,而只需要对作为分支目标的行进行编号。实际上,是标签。


3
肉汁很好,我忘了迷你拼装机。那带回了回忆
Blrfl

3
@Blrfl如果有内存可用...是的] CALL -936 * F666 G $ ... ,FP基本入门。

3
不,那行编辑器。通过没有行号来识别命令。语句前面有行号,以表明它们既是语句,又表明它们去了和/或改写了哪一行。那是BASIC的内置行编辑器部分,它不是独立的工具或环境。
RBarryYoung '16

3
@RBarryYoung ] PRINT "FOO"由BASIC解释器立即运行。这是一个声明。如果你想稍后再运行它,你会怎么做] 10 PRINT "FOO",然后] RUN。在AppleSoft BASIC环境中,每个BASIC语句都可以立即运行或延迟运行-DOS提供的命令很少,这些命令不是有效的BASIC语句。现在的语句和以后的语句之间的区别是行号。您也可以通过重新输入相应的行号来修改延迟的语句。您也可以在一行上放置多个语句::

4
如Wikipedia文章(en.wikipedia.org/wiki/Dartmouth_BASIC)所述,“ DTSS(达特茅斯时间共享系统)实现了早期的……交互式命令行界面。...以行号开头的任何行都被添加到程序,用相同的编号替换以前存储的任何行;其他任何东西都假定为DTSS命令并立即执行....由于使用电传打印机作为Dartmouth Timesharing系统的终端单元,因此这种编辑方法是必需的。
RBarryYoung '16

50

在早期的微型计算机上,编辑是基于行的。您不能随便在源代码中自由移动并进行编辑。屏幕底部只有一行,您可以在其中键入命令并输入代码。屏幕的其余部分是只读代码列表和命令输出。如果要编辑,请在程序中说第90行,您编写了“ EDIT 90”,然后行的内容90输入了单行编辑缓冲区。编辑完该行后,请按Enter键,并且程序清单已更新。因此,您需要行号才能编辑程序。

当代码编辑器变得更加高级并允许您在代码清单中移动光标时,您不再需要行号。


38
编辑线?豪华!我使用的第一批BASIC使您重新键入整行。当您必须重新编号子例程时,这确实很糟糕。
TMN

48
屏幕?什么屏幕?在我的第一个Basic中,“屏幕”是一卷纸。
ddyer

18
@ddyer:我曾经梦想过要卷纸!所有我们曾是一帮电极。在应该完成工作的晚上,我们必须排成一排,观察谁被电死,以查看程序是否正常工作。……-说真的,我很吃惊,当时人们实际上设法编写了工作程序。
大约

26
电力!血腥的奢华。我们用凿我们的命令列于花岗岩
迈克尔·达兰特

10
@TMN和ddyer好吧,你们俩都知道前进的方向,对吧?;-D ==> dilbert.com/strip/1992-09-08 ==> imgs.xkcd.com/comics/real_programmers.png
Baard Kopperud,2016年

45

如果您正在考虑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

我们刚刚解决的更多问题

能够将行号用作语言构造(至少作为GOTOAND GOSUB命令的目标)是有好处的(或受诅咒的,因为它使著名的BASIC意大利面条代码成为可能)。可以用标签代替,但是在BASIC解释器中使用行号要容易得多,这在80年代典型的8位家用计算机中仍然是绝对的优势。

更重要的是,从用户体验的角度来看,行号确实是一个令人惊讶的简单而完整的代码编辑界面。只需键入以数字开头的行即可插入新代码。使用LIST 100-200显示线100-200。要编辑一行,请在屏幕上列出该行,在屏幕上编辑文本,然后重新输入行。要删除一行,请将其编辑为空,即只需给行号加上任何空格。一段描述了这一点。比较一下尝试描述使用旧文本编辑器(如DOS的edlin或Unix的edex)的情况:您需要一个段落(仅略微夸张)来说明用户意外启动时如何退出它们!

结论

其他答案解释了行号是如何变成的。我试图在这里介绍行号为什么能生存如此长的时间,如何继续解决现实世界的问题:它们提供了一种无需真正编辑器即可以非常简单的方式进行实际编程的方法。一旦适当,易于使用的全屏文本编辑器成为编辑代码的主流方式,这不仅消除了硬件限制,而且克服了人们适应新事物的惯性,然后基于行号的BASIC方言很快就从使用中消失了,因为他们解决的核心可用性问题不再是问题。


4
你钉了 使用多行屏幕而不是仅打印tty或单行可以简化操作,但是如果没有源文件概念,它仍然是面向行的。
JDługosz

但是,系统是8位架构这一事实实际上并不是限制因素。现在,该系统可能只有几千字节的RAM和几千字节的ROM,甚至可能没有永久存储(如果您的盒式磁带录音机坏了)……
CVn

如果没有文本编辑器,仍然很难想象编码
phuclv

@LưuVĩnhPhúc好吧,有很多用于运行“真实事物”的仿真器,例如几乎任何8位家用计算机,MSDOS及其带有dosbox的GWBASIC。举例来说,您可以获得众多C64模拟器之一,然后Google可以找到其用户指南,PDF格式:-)
hyde

1
@phuclv-现在很难想象没有文本编辑器的编码。当时,很难想象必须使用文本编辑器,保存它并在运行它之前对其进行编译的不便……这确实是PC世界的下一步。Pascal和C。两种编译语言都可以使用文本编辑器自由编辑,它们本身绝对不是编程环境(BASIC既是编程环境又是运行时环境)。Pascal是我的下一种语言,并且在许多方面都非常解放。绝对更强大。但是在其他方面,则少一些激动。
DavidO

17

在开发Basic的时代和时代,最好的I / O设备是电传打字机。通过打印(在纸上)整个程序的列表或其中有趣的部分,然后键入带有行号的替换行来完成程序的编辑。

这就是默认行号加10的原因,因此现有行之间会有未使用的数字。


1
实际上,与电传打印机相比,读卡器(带有按键)和行式打印机是更好的I / O设备,但电传打印机便宜得多。
超级猫

行编号为10是事实上的标准,而不是严格的要求。许多BASIC都有一个' ren'命令,以进行重新编号。一个典型的调用是ren 10, 10(重新编号开始十,十递增-默认行为,如果一个刚键入rengotogosubthen (linenumber)。命令会自动更新,但是,这绝对不是最早的基本可用,但IIRC,在苹果公司提供。整数基础,Applesoft FP基础,TI基础/扩展基础,MS基础/ GW基础等
DavidO

13

“行号”表示一些不同的内容。

首先,请记住,“线条”的概念并没有永远存在。这个时代的许多编程语言都使用打孔卡,并且具有序列号(通常在卡的最后几列中)可以帮助您以正确的顺序恢复卡组(如果您放下了卡组),或者读卡器中发生了一些糟糕的事情。有机器自动执行此操作。

用作GOTO语句目标的行号是一个完全不同的概念。在FORTRAN IV中,它们是可选的,位于语句之前(在1-5列中)。除了比自由格式的标签更易于实现之外,还有计算和分配的GOTO的概念,它使您可以跳转到任意行号。这是大多数现代编程语言所没有的(尽管switch语句很接近),但这是汇编程序员熟悉的技巧。

BASIC是从FORTRAN派生的,其意图是更易于实现和理解,因此,强制每个“行”都具有行号(既用于排序又作为GOTO/ GOSUB语句的目标)是出于这个原因而做出的设计决策。


2
嗯,计算并分配了gotos。PL / 1中的标签变量数组的内存,循环遍历一个数组以查找匹配项,然后使用匹配的数组索引作为标签变量数组中的索引来进行跳转。或Cobol改变了态度。而且都不使用行号!BBC基本版有一个非常有用的重新编号声明。
Kickstart '02

GCC允许将计算得出的GOTO用作扩展名(尽管当然不能直接使用行号)-您可以做类似的事情goto array_of_labels[some_computation()];
immibis

辅修:对目标FORTRAN所需标签GOTO(或ASSIGN)与原又名算术又名三通IF,以及(很少使用)的交替返回CALL,和排序的-目标(可以说是分隔符)DO,和FORMAT语句。在其他陈述中,它们是可选的。
dave_thompson_085 '02

某些BASIC(例如Atari)甚至允许在GOTO语句中使用任意数字表达式。因此,使用适当的行编号约定,您可以编写GOTO 1000+N*100仿真switch语句。
dan04 '02

6

我开始使用COBOL编程,该编程使用每行1-6列中的行号。因为在1970年代没有IDE,所以一切都是通过打孔卡完成的,并且使用行号来标识要替换原始源中的哪些行以及添加哪些新行。我们过去通常将行号增加100,以便给我们增加更多行的空间。


14
COBOL没有使用这些行号。严格来说,它们是一种便利,因此当一些可怜的schlub放下甲板,到处都是卡片时,他可以将它们收集起来并通过卡片分拣机运行,以使其恢复正确的顺序。您无需将行号打入卡中。(学生没有。生产工厂也有。)
John R. Strohm,

5

在线路终端时代,BASIC的出现要晚于FORTRAN。它具有一个read-exe-print-loop环境,它比一副纸牌更具交互性。

我学会了用BASIC在一行包含24个字符的显示器上编程。行号是一种自然的方式,它可以指定要移到的行,无论是编辑一条还是插入其他一条。

我真的无法想象你还会怎么做。


2
在先前的4个答案中,这似乎并没有提供实质性的要点和解释
gnat

2
这很糟糕吗?我认为Jaques并没有真正涵盖单行编辑在插入行和心理跟踪代码方面的精髓。
JDługosz

1
@jameslarge我是否在以“使用BASIC工作很多次...”开头的段落中错过这一点?我也犹豫将BASIC称为操作系统。那是DOS。而且DOS不需要BASIC,这正是您大部分时间都可以使用的

2
@Ian而这是真的,它被设计为使用电传打字机的IO(达特茅斯分时系统)的系统。
2013年

3
@MichaelT,糟糕!我将撤回一半的评论,但我会坚持关于BASIC是某些计算机上的操作系统的部分。我在想; Apple],TI 99/4,IBM 5100,HP 9830a,Compucolor 8001,TRS-80 Model 1,Comodore Vic20,Sinclair ZX80等。全部从ROM启动到BASIC。有些具有可选的操作系统,可以从音频盒或软盘中加载,如果您为软驱支付了额外的$$,则可以从中加载。
所罗门慢

1

还没有人提到的一点是,对于初学者来说,在分支目标明确的情况下,更容易对程序流程进行推理。因此,不必匹配(可能嵌套)BEGIN / END语句(或使用了任何块定界符),控制流的位置就很明显了。对于BASIC的目标受众来说,这可能很有用(毕竟,它是初学者的通用符号指令代码)。


1

达特茅斯分时系统使用了电传打字机界面。因此,它使用了基于命令的界面。最初,行号只是用来编辑程序的。您可以使用行号插入,替换或删除。早期版本似乎没有为goto语句使用行号,但这是该语言的后来版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.