最近,我感到怀旧,因此决定安装Commodore-64仿真器。 C-64 BASIC 2.0是20年前我曾经编程的第一门语言(是的,C-64到那时已经不推荐使用了)。

在这种语言中实现简单的Fizzbuzz有限的语言,以及至少在过去十年中我几乎学不到的所有知识,以Q4312079q和行号在程序范式中编写代码,这比我想象的要有趣(而且棘手!)。

这是代码-我将输出限制为15个值,以便可以在屏幕上看到整个序列。

10 GOSUB 100
20 GOSUB 1000
99 END
100 REM CLEAR SCREEN
110 PRINT CHR$(147)
120 RETURN
200 REM MODULO
210 LET MOD% = V%-INT(V%/FB%)*FB%
220 RETURN
1000 REM INIT VARIABLES
1010 LET FIZZ$ = "FIZZ"
1011 LET BUZZ$ = "BUZZ"
1020 LET FIZZ% = 3
1021 LET BUZZ% = 5
1030 LET MIN% = 1
1031 LET MAX% = 15
1100 PRINT FIZZ$ + ":" + STR$(FIZZ%)
1101 PRINT BUZZ$ + ":" + STR(BUZZ%)
1102 PRINT FIZZ$ + BUZZ$ + ":" + STR$(FIZZ%*BUZZ%)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN% TO MAX%
2015 LET RESULT% = STR$(X)
2020 LET FB% = FIZZ%*BUZZ%
2021 LET V% = X
2024 GOSUB 200
2025 IF MOD%=0 THEN LET RESULT$=FIZZ$+BUZZ$ : GOTO 2050
2030 LET FB% = FIZZ%
2031 GOSUB 200
2035 IF MOD%=0 THEN LET RESULT$=FIZZ$ : GOTO 2050
2040 LET FB% = BUZZ%
2041 GOSUB 200
2045 IF MOD%=0 THEN LET RESULT$=BUZZ$ : GOTO 2050
2050 PRINT RESULT$
2090 NEXT X
2099 RETURN


输出:



这听起来很奇怪,但是实际上C-64代码是一个很大的问题,所以不要笑(好吧,笑,但这不是在开玩笑) :我的行号如何?

我试图以这样的方式编写代码:可以很容易地扩展为提示用户输入GOTOMIN%值,还可以提示用户MAX%FIZZ%;我还关心实现“模”子例程,因为我知道逻辑必须在3个地方使用。

多年来,我失去了很多语言的功能(最大的挑战)确实是暂时停止在对象和方法方面进行思考了)。语言中有什么可以帮助改进此代码的内容吗?

除此之外,是否存在任何不一致或怪异的地方?

评论

不,你没有...等等...是的,你确定是这样。

@glampert我相信他不会使用序号,因此,如果他以后要添加更多行,则不必更改每个行号。

@glampert序列号的问题在于它将代码强制转换为固定值,并且无法更改或扩展它。

嗯,是的,这很有意义,感谢您的澄清!

变量名中只有两个字母有意义。长名称有助于提高可读性,但是我想知道这是否超过了不注意两个不同名称用于同一变量的风险吗?

#1 楼

首先,谢谢您让我想起过去的美好时光!
BUG警报
好吧,这并不是一个错误,但是您知道后缀%表示该变量将是一个integer

2010 FOR X = MIN% TO MAX%
2015 LET RESULT% = STR$(X)
2020 LET FB% = FIZZ%*BUZZ%


,但是您要为其分配STR$()的结果,即string
因此将RESULT%更改为RESULT$会有所帮助,但是仍然会调用此STR$()方法,因为如果模返回0,则该值将被覆盖。因此,将其放在PRINT RESULT$上方的行上将使其更具光泽。
FIZZ%BUZZ%都不会改变,因此在循环内调用LET FB% = FIZZ%*BUZZ%是一个坏主意。 FB%变量应在其他变量被声明和初始化的地方声明和初始化。

LET
可以省略为变量分配值的LET命令,因为可以在没有变量的情况下为变量分配值。另外,如果省略它们,则将节省一些内存并减少执行时间。

DEF FNFN
定义和调用“函数”,将减少一些GOSUB的调用,并使您的代码更漂亮。
所以我建议定义3个这样的函数
5 DEF FN FIZZMOD(V) = V-INT(V/FIZZ%)*FIZZ%
6 DEF FN BUZZMOD(V) = V-INT(V/BUZZ%)*BUZZ%
7 DEF FN FBMOD(V) = V-INT(V/FB%)*FB%


样式在过程语言中很重要。
随着GOTO的广泛使用,和GOSUB区分程序的各个部分非常重要。
通过在前面加上“空” REM和在“定义”“ sub”的REM之后,可以很容易地了解它的含义。然后,看起来您将用新行将逻辑部分分组,但是不幸的是,仅行号就无法完成。
这样
200 REM 
201 REM MODULO
202 REM 
210 LET MOD% = V%-INT(V%/FB%)*FB%
220 RETURN

@psmears在注释中给出了很好的提示

另一种方法(看起来比没有文本的REM更干净)是在行上保留一个“:”。 br />

在顶部使用更多REM语句表示例如GOSUB 100会做什么

应用此操作将导致
 1 REM GOSUB 100 > CLEAR SCREEN
 2 REM GOSUB 1000 > INIT VARIABLES
 3 REM GOSUB 1100 > FIZZ BUZZ
 4 REM
 5 DEF FN FIZZMOD(V) = V-INT(V/FIZZ%)*FIZZ%
 6 DEF FN BUZZMOD(V) = V-INT(V/BUZZ%)*BUZZ%
 7 DEF FN FBMOD(V) = V-INT(V/FB%)*FB%
 9 REM
10 GOSUB 100
20 GOSUB 1000
30 GOSUB 1100
99 END
100 REM
101 REM CLEAR SCREEN
102 REM
110 PRINT CHR$(147)
120 RETURN
200 REM
1000 REM 
1001 REM INIT VARIABLES
1002 REM
1010 FIZZ$ = "FIZZ"
1011 BUZZ$ = "BUZZ"
1020 FIZZ% = 3
1021 BUZZ% = 5
1022 FB% = FIZZ% * BUZZ%
1030 MIN% = 1
1031 MAX% = 15
1032 RETURN
1090 REM
1091 REM FIZZ BUZZ 
1092 REM
1100 PRINT FIZZ$ + ":" + STR$(FIZZ%)
1101 PRINT BUZZ$ + ":" + STR(BUZZ%)
1102 PRINT FIZZ$ + BUZZ$ + ":" + STR$(FB%)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN% TO MAX%
2025 IF FN FBMOD(X)=0 THEN RESULT$=FIZZ$+BUZZ$ : GOTO 2050
2035 IF FN FIZZMOD(X)=0 THEN RESULT$=FIZZ$ : GOTO 2050
2045 IF FN BUZZMOD(X)=0 THEN RESULT$=BUZZ$ : GOTO 2050
2049 RESULT$ = STR$(X)
2050 PRINT RESULT$
2090 NEXT X
2099 RETURN

代码行不再使用或被移动了
,我没有测试结果程序,因为模拟器不允许我加载文件。粘贴代码也不起作用。我测试了MOD的东西,它起作用了。

评论


\ $ \ begingroup \ $
+1用于保留空白行以强调子例程的开始。执行此操作的另一种方法(看起来比没有文本的REM更干净)是在行上仅留下“:”。
\ $ \ endgroup \ $
–psmears
2015年9月3日,9:53

#2 楼

对于像我这样老的人来说,这些都是傻笑的,下面是OP代码的TI BASIC版本。请注意,TI BASIC(甚至TI扩展BASIC)没有整数运算的概念。都是浮点数。同样,语言本身不像当今的大多数BASIC一样被解释,而是由解释器解释-也就是说-BASIC解释器是用一种称为GPL的语言编写的,该语言本身是在GPL解释器下运行的。安慰。此外,用户程序存储在称为VDP的端口映射存储器中,该存储器通过单个存储器地址一次或一次读取或写入。与同期的语言相比,这导致了该语言臭名昭著的缓慢。历史课的反义词:)

10 GOSUB 100
20 GOSUB 1000
99 END
100 REM CLEAR SCREEN
110 CALL CLEAR
120 RETURN
200 REM MODULO
210 LET MOD = V-INT(V/FB)*FB
220 RETURN
1000 REM INIT VARIABLES
1010 LET FIZZ$ = "FIZZ"
1011 LET BUZZ$ = "BUZZ"
1020 LET FIZZ = 3
1021 LET BUZZ = 5
1030 LET MIN = 1
1031 LET MAX = 15
1100 PRINT FIZZ$ & ":" & STR$(FIZZ)
1101 PRINT BUZZ$ & ":" & STR$(BUZZ)
1102 PRINT FIZZ$ & BUZZ$ & ":" & STR$(FIZZ*BUZZ)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN TO MAX
2015 LET RESULT$ = STR$(X)
2020 LET FB = FIZZ*BUZZ
2021 LET V = X
2024 GOSUB 200
2025 IF MOD<>0 THEN 2030
2026 LET RESULT$=FIZZ$&BUZZ$
2027 GOTO 2050
2030 LET FB = FIZZ
2031 GOSUB 200
2035 IF MOD<>0 THEN 2040
2036 LET RESULT$=FIZZ$
2037 GOTO 2050
2040 LET FB = BUZZ
2041 GOSUB 200
2045 IF MOD<>0 THEN 2050
2046 LET RESULT$=BUZZ$
2047 GOTO 2050
2050 PRINT RESULT$
2090 NEXT X
2099 RETURN


和海斯拉赫的回答翻译为:

 1 REM GOSUB 100 > CLEAR SCREEN
 2 REM GOSUB 1000 > INIT VARIABLES
 3 REM GOSUB 1100 > FIZZ BUZZ
 4 REM
 5 DEF FIZZMOD(V) = V-INT(V/FIZZ)*FIZZ
 6 DEF BUZZMOD(V) = V-INT(V/BUZZ)*BUZZ
 7 DEF FBMOD(V) = V-INT(V/FB)*FB
 9 REM
10 GOSUB 100
20 GOSUB 1000
30 GOSUB 1100
99 END
100 REM
101 REM CLEAR SCREEN
102 REM
110 CALL CLEAR
120 RETURN
200 REM
1000 REM 
1001 REM INIT VARIABLES
1002 REM
1010 FIZZ$ = "FIZZ"
1011 BUZZ$ = "BUZZ"
1020 FIZZ = 3
1021 BUZZ = 5
1022 FB = FIZZ * BUZZ
1030 MIN = 1
1031 MAX = 15
1032 RETURN
1090 REM
1091 REM FIZZ BUZZ 
1092 REM
1100 PRINT FIZZ$ & ":" & STR$(FIZZ)
1101 PRINT BUZZ$ & ":" & STR$(BUZZ)
1102 PRINT FIZZ$ & BUZZ$ & ":" & STR$(FB)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN TO MAX
2025 IF FBMOD(X)<>0 THEN 2035
2026 RESULT$=FIZZ$&BUZZ$
2027 GOTO 2050
2035 IF FIZZMOD(X)<>0 THEN 2045
2036 RESULT$=FIZZ$
2037 GOTO 2050
2045 IF BUZZMOD(X)<>0 THEN 2049
2046 RESULT$=BUZZ$
2047 GOTO 2050
2049 RESULT$ = STR$(X)
2050 PRINT RESULT$
2090 NEXT X
2099 RETURN