跳转至内容

QBasic/完整书籍视图

来自维基教科书,开放书籍,为开放世界

基本输入

[编辑 | 编辑源代码]

INPUT 命令用于从用户那里收集输入。本节将尝试教你如何根据用户的请求收集输入。有关实时输入,请参阅 QBasic/高级输入

以下是 input 命令的语法

INPUT "[text to user]"; [variable] ' Question mark added

INPUT "[text to user]", [variable] ' No question mark added

示例

INPUT "What is your name"; name$

INPUT "What is your age", age

在向用户输出文本后使用分号 (;) 时,将在输出中添加问号 (?) 和空格 ( )。使用逗号 (,) 时,不会添加问号。

如果指定字符串(例如,'name$'),则用户在按“回车”键之前输入的任何内容都将被接受。

如果指定数值变量(例如,'age'),则用户必须输入数字。如果输入任何非数字键,则将输出错误消息“从头开始重做”,并重新运行 INPUT 命令。

6INPUT.BAS

[编辑 | 编辑源代码]
CLS
INPUT "What is your name"; name$
PRINT "Hello, "; name$; 
INPUT "How old are you"; age
INPUT "What is your best computer game?", game$
PRINT "     name:"; name$
PRINT "      age:"; age; " years old"
PRINT "best game:"; game$

请注意:在 PRINT 命令中,(;) 函数连接(合并)字符串变量的内容与引号 (" ") 之间的文本。请注意空格的使用,以便最终打印的文本正确读取。

如果在 PRINT 命令中指定了数值变量,则会在数字之前和之后自动添加额外的空格。

另请参阅:LINE INPUT 命令用于从文件读取一行文本(并将结果放入字符串变量中),或输入一系列变量(在这种情况下,找到的任何逗号将被视为字段之间的分隔符)。

INPUT # 和 LINE INPUT

[编辑 | 编辑源代码]

INPUT # 使用打开的文件流从文件本身收集数据。该文件可以是数据文件、位图或文本文件。语法为

INPUT #file_stream, variable1 ; variable2$ ' more variables can be taken.

LINE INPUT 用于收集文本文件中的整行。语法

LINE INPUT 1,file_line '1 is the file stream number. Can be any other number too.

警告:如果输入超过文件末尾,将发出错误: "输入超过文件末尾 "。可以使用 LOFEOF 函数来防止错误。(LOF 代表文件长度,而 EOF 代表文件结尾)

文本输出

[编辑 | 编辑源代码]

你的第一个 QBasic 程序: 1HELLO.BAS

[编辑 | 编辑源代码]

以下段落需要安装了 QBasic 的计算机

首先,将以下程序中的所有内容(“PRINT "Hello World"”)写入文本编辑器或 QBasic IDE(集成开发环境)本身,并将其保存为“1HELLO.BAS”。接下来,在 QBasic 中打开该文件(除非你使用的是 QBasic IDE,在这种情况下它已经打开),然后按 F5 键。你也可以使用 IDE 窗口顶部的菜单栏上的“运行”菜单。这将执行(运行)该程序。单词“Hello World”应出现在屏幕的左上角。你刚刚执行了第一个 QBasic 程序。如果你再次按 F5,另一行文本“Hello World”将出现在屏幕的左上角,将第一行推到屏幕的第二行。你可以对本维基教科书中的其他示例程序遵循相同的步骤。

1HELLO.BAS

[编辑 | 编辑源代码]
 PRINT "Hello World"

PRINT 是 QBasic 的文本输出函数。它是我们将通过本节探索的命令。PRINT 是 QBasic 函数,需要参数。我们刚刚运行的“Hello, World!”程序中的参数是单词“Hello, World!”。因此,PRINT 是函数,“Hello, World!”是我们传递给函数的参数。

PRINT [屏幕文本]

注意:作为快捷方式,只需使用问号“?”代替命令“PRINT”。同样,可以使用单引号“'”代替关键字 REM 来在代码中插入注释

2HELLO.BAS

[编辑 | 编辑源代码]
 PRINT "This line will be erased"
 CLS
 PRINT "Hello";
 PRINT " World",
 PRINT "Hello Jupiter"
 PRINT "Good Bye",,"For";" Now"
 PRINT 1,2,3,4,5

PRINT、逗号、分号、制表符 (n) 和 CLS

[编辑 | 编辑源代码]

以下是程序输出应显示的样子

Hello World   Hello Jupiter
Good Bye                    For Now
 1             2             3              4              5

2HELLO.BAS 的第一行将“This line will be erased.”输出到屏幕。但是,在第二行中,CLS 命令在立即清除屏幕后执行。因此,它只会闪烁一下。文本“Hello Jupiter”应与下面的“2”对齐。可以连续使用多个逗号。在本例中,在“Good Bye”之后使用了两个逗号,将“For Now”移动到两个制表符列上。“For Now”应与“3”对齐。

关于此主题的最后一句话是,尝试一下。尝试在程序中使用逗号和分号。

3HELLO.BAS

[编辑 | 编辑源代码]
 CLS
 hello$ = "Hello World"
 number = 12
 PRINT hello$, number

变量用于存储信息。它们就像容器。你可以在其中放入信息,然后稍后将信息更改为其他内容。在第一个示例中,它们可能看起来不太有用,但在下一节(输入)中,它们将变得非常有用。

在本例中,我们使用两种类型的变量:字符串变量和数值变量。字符串变量保存字符串,例如单词。(字符是字母、数字或符号。)在本例中,字符是字母。字符串变量用美元符号表示变量名称的结尾。本程序中的字符串变量是 hello$。你为 hello$ 分配的任何值都将在 PRINT 语句中显示。数值变量是 number。数值变量没有像字符串变量那样的特殊结尾。

4FACE.BAS

[编辑 | 编辑源代码]
CLS
LOCATE 14, 34     'position the left eye
PRINT "<=>"       'draw the left eye
LOCATE 14, 43     'position the right eye
PRINT "<=>"       'draw the right eye
LOCATE 16, 39     'position the nose
PRINT "o|o"       'draw the nose
LOCATE 18, 36     'position the mouth
PRINT "\_______/" 'draw the mouth
LOCATE 19, 42     'the bottom
PRINT "The Face by QBasic"

LOCATE 语句

[edit | edit source]

LOCATE 用于定位光标以输出下一段文本。与读取 (X,Y) 的笛卡尔坐标相反,locate 语句为 LOCATE Y,X。在这种情况下,Y 是从屏幕顶部向下移动的距离,而 X 是从屏幕左侧移动的距离。LOCATE 不遵循标准坐标系的原因是,它不需要包含 X 部分;可以使用 LOCATE Y 格式,它只指定要开始的行。

LOCATE[row, column]
LOCATE[row]

5FACE.BAS

[edit | edit source]
 CLS

 LOCATE 14, 34
 COLOR 9
 PRINT "<=>"

 LOCATE 14, 43
 PRINT "<=>"

 COLOR 11
 LOCATE 16, 39
 PRINT "o|o"

 COLOR 4
 LOCATE 18, 36
 PRINT "\_______/"

 COLOR 20
 LOCATE 19, 42
 PRINT "U"

 LOCATE 1, 1
 COLOR 16, 1
 PRINT "Hello World"

COLOR 语句

[edit | edit source]

5FACE.BAS 程序被分成很多部分,以便于阅读。这是一个好的编程习惯的例子。每三行代码指定了人脸部分的颜色、位置和形状。位置和颜色的顺序无关紧要。新的 COLOR 语句允许您更改文本的颜色。一旦更改,所有输出都将以新颜色显示,直到使用 COLOR 或 CLS 为止。

COLOR [foreground]
COLOR [foreground], [background]

颜色由数字指定,将在下一节中讨论。

颜色编号

[edit | edit source]

有 16 种颜色(在屏幕模式 0 中),从 0 到 15 编号。

0 黑色 8 灰色
1 蓝色 9 浅蓝色
2 绿色 10 浅绿色
3 青色 11 浅青色
4 红色 12 浅红色
5 紫色 13 浅紫色
6 棕色/橙色 14 黄色(浅橙色)
7 浅灰色(白色) 15 白色(浅白色)

如果您仔细观察此图表,您会发现有 8 种主要颜色(0 到 7),然后这些颜色重复,每种颜色都以更浅的色调显示。您可能还会注意到颜色充当二进制值的组合(其中蓝色=1,绿色=2,红色=4 等)。这使得记忆颜色方案变得容易得多。闪烁颜色也可用:从 16 开始,颜色再次开始闪烁黑色并延伸到 31(闪烁白色)。但是,闪烁选项不可用于背景,仅用于文本(前景)。在您要闪烁的颜色中添加 16。例如:2+16=18 - 闪烁的绿色,4+16=20 - 闪烁的红色。

可以使用闪烁的前景文本和强烈的背景,但这超出了本 QBasic 教科书的范围,并且可能在 MS Windows 在窗口模式下显示控制台时不起作用。

字体

[edit | edit source]

在 VGA 兼容的显卡上,您可以检查和更改屏幕模式 0 中使用的字体。

OUT &H3CE, 5: OUT &H3CF, 0 'Clear even/odd mode
OUT &H3CE, 6: OUT &H3CF, 4 'Map VGA mem A0000-BFFFF
OUT &H3C4, 2: OUT &H3C5, 4 'Set bit plane 2
OUT &H3C4, 4: OUT &H3C5, 6 'Clear even/odd mode again

您现在可以使用 PEEK 和 POKE 访问字符数据。它从绝对地址 &HA0000 开始,每个字符为 32 字节,每个字节都是八位的一行。每个字节的最高位对应于每行的最左侧像素。通常仅使用前 16 行或 8 行,具体取决于 WIDTH 设置。

完成后,请务必将内存映射恢复到 QBasic 所期望的设置

OUT &H3CE, 6: OUT &H3CF, 14 'Map VGA mem B8000-BFFFF

总结

[edit | edit source]

在本节中,我们介绍了几种操作文本输出的方法。所有内容都围绕 PRINT 语句展开。LOCATE 和 COLOR 修改了文本的显示位置及其外观。我们使用 CLS 清除屏幕,并简要介绍了变量,这些变量将在后面的部分中进行扩展。

基础数学

[edit | edit source]

QBasic 中有六种数值变量

类型 最小值 最大值
整数 -32,768 32,767
长整数 -2,147,483,648 2,147,483,647
浮点数 -3.37x10^38 3.37x10^38
双精度浮点数 -1.67x10^308 1.67x10^308
64 位整数 -9,223,372,036,854,775,808 9,223,372,036,854,775,807
64 位浮点数 ±1.18E−4932 ±1.18E+4932

请注意,只有在 QB64 中才可以使用 64 位的整数和浮点数类型的变量。

很多编程都是数学。别担心:很多数学都很简单,但它仍然是数学。在本节中,我们将学习一些基本数学(与您在三年级学到的内容相同)以及操作数字。

方程式设置

[edit | edit source]

在 QBasic 中,方程式具有基本设置,即右边和左边。例如 X=5,您可能已经猜到,这将变量 X 设置为 5。但我们也可以在右边使用变量。Y=X*10 将 Y 设置为 X 的 10 倍,在这种情况下为 50。在下一个程序中,我将展示几个方程式,让您了解数学。

7MATH.BAS

[edit | edit source]
 CLS
 
 'Set a-d to initial values
 a = 10
 b = 6
 c = 3.1415
 d = 3.333333
 
 e = a + b
 PRINT a; "+"; b; "="; e
 
 f = c * d
 PRINT c; "x"; d; "="; f
 
 g = b - c
 PRINT b; "-"; c; "="; g
 
 h = b / d
 PRINT b; "/"; d; "="; h
 
 i = INT(d)
 PRINT "Remove the decimal from "; d; "="; i

理解 7MATH.BAS

[edit | edit source]

您从中学到的最重要的内容是数学方程式的设置。我认为您可以弄清楚所有符号的含义以及它们的作用,但 QBasic 对方程式很挑剔。对于“e=a+b”,如果您尝试“a+b=e”,它将无法工作。我想在 7MATH.BAS 中解决的最后一件事是 INT() 函数。就词汇而言,函数是指接受一段信息并为您返回另一段信息的东西。因此 PRINT 是一个语句,而 INT() 是一个函数。INT() 函数接受一个数字并截断其小数部分,它不进行四舍五入。因此 INT(5.1) 为 5,INT(5.999) 仍然为 5。如果您要四舍五入数字,请使用 CINT()。

8MATH.BAS

[edit | edit source]
 CLS
 INPUT "Enter a number: ", x
 PRINT
 
 x = x + 5
 PRINT "X is now: "; x
 
 x = x * x
 PRINT "X is now: "; x
 
 x = x / 5
 PRINT "X is now: "; x
 
 x = x - 4
 PRINT "X is now: "; x
 
 x = x / x
 PRINT "X should be 1: "; x

理解 8MATH.BAS

[edit | edit source]

8MATH.BAS 展示了一个在编程中非常重要但在数学中不可能实现的简单概念。计算机计算方程式的过程是在方程式右边进行所有数学运算,然后将其粘贴到左边的变量中。因此方程式 x=x+5 非常有意义,与数学中的矛盾不同。根据当前值重新分配变量的值很常见,也是减少变量数量的好方法。

9TIP.BAS

[edit | edit source]
 CLS
 INPUT "How much is your bill: ", bill
 INPUT "What percent tip do you want to give: ", tip
 
 tip = tip / 100   'change percent to decimal
 tip = tip * bill  'change decimal to money
 
 PRINT
 PRINT "The tip is"; tip; "$."
 PRINT "Pay"; tip + bill; "$ total."

小费计算器

[edit | edit source]

9TIP.BAS 根据您希望给的小费百分比和账单,计算您的小费和总账单。前三行清除屏幕并从用户处获取信息。第五行将小费从百分比更改为正确的十进制数,方法是除以 100(例如,20%=.2 因为 20/100=.2)。下一行将该百分比乘以账单,将其转换为美元价值。因此,如果您的账单为 20.00 美元,并且您付了 20% 的小费,它将乘以 20*.2,即 4 或 4.00 美元。最后三行格式化输出。
这是一个完整的程序的好例子。它从用户那里收集信息,处理信息,并向用户提供反馈。此外,程序的中间部分是变量保存的一个很好的例子。这是一个需要一些练习才能掌握的主题。在编写程序时,如果您使用太多变量,将很难跟踪所有变量。如果您尝试过度节省,您的代码可能难以理解。

您可能会注意到,如果您输入的账单金额不是精确的美元值,程序可能会输出超过两位小数。作为练习,尝试修改程序,使其只显示两位小数 - 您可以使用 `CINT()` 函数或任何您打算使用的其他舍入方法。

10OROP.BAS

[编辑 | 编辑源代码]
 'ORder of OPerations
 CLS
 a = 15
 b = 10
 c = 12.2
 d = 1.618
 
 PRINT a * b + c   'these two are different
 PRINT a * (b + c)
 
 PRINT
 
 PRINT b - c / d   'these two are different
 PRINT (b - c) / d
 
 PRINT
 
 PRINT a * b - c * d / a + d   'these two are the same
 PRINT (a * b) - ((c * d) / a) + d

括号和运算顺序

[编辑 | 编辑源代码]

10OROP.BAS 是运算顺序和如何使用括号来操纵它的一个例子。我不打算在这里深入解释运算顺序。我能给出的最好的建议是,除非您确定运算顺序,否则请使用括号来确保方程式按您想要的方式工作。您只需要知道括号是,最深层的嵌套括号首先计算。如果您想了解更多信息,有很多代数资源可用。关于这一点,您可能希望复习一下代数。虽然它对于编程不是必需的,但它可以帮助简化编程,并使您能够创建更高级的程序。

随机数

[编辑 | 编辑源代码]

虽然我们将在下一节中讨论它们的用途,但我希望讨论随机数的生成。QBasic 有一个随机数语句 RND,它生成一个介于 0 和 1 之间的随机小数。您可以将其视为一个随机百分比。起初,这可能看起来像一个奇怪的生成随机数的方式。但是,用一点数学知识,很容易操纵它来提供您想要的任何范围内的数字。
第一步是用一个数字(您想要的范围)乘以 RND。例如 'RND*10'。这将返回介于 0 和 10(包括 0 和 10)之间的随机数(小数)。因此,要选择一个介于零和十之间的随机数,我们会说 '(RND*10)'

11RND.BAS

[编辑 | 编辑源代码]
 CLS
 RANDOMIZE TIMER
 
 PRINT "Random number from 0-9:"; RND * 10
 PRINT
 
 PRINT "Random number from 1-10:"; (RND * 10) + 1
 PRINT
 
 PRINT "Random integer from 1-10:"; INT(RND * 10) + 1
 PRINT
 
 PRINT "Random even integer from 50-100:"; INT(RND * 25) * 2 + 50

关于 RND 的更多信息

[编辑 | 编辑源代码]

关于 11RND.BAS 的一些说明,第二行 RANDOMIZE TIMER,设置计算机使用当前时间来选择随机数。如果您不这样做,它每次都会选择相同的随机数(试试看,编写一个单行程序,PRINT RND,并反复运行它,您的屏幕将充满相同的数字)这对于某些应用程序来说可能很有用,但对于大多数应用程序来说则不然。在所有使用 RND 语句的程序的顶部添加 RANDOMIZE TIMER,它们将变得不那么可预测。这个程序只展示了一些从随机数生成器中选择所需内容的方法。最后一行显示您可以对得到的内容非常具体。确保运行此程序几次,以查看不同的结果。

流程控制

[编辑 | 编辑源代码]

条件执行

[编辑 | 编辑源代码]

要从程序的两个或多个部分中选择要执行的部分,可以使用 IF 语句。还可以使用 WHILE、DO UNTIL 和 CASE 语句。所有这些都通过使用布尔逻辑“测试”来控制条件执行,测试的结果要么为 TRUE 要么为 FALSE。要重复一段代码一定次数,可以使用 FOR 语句。

IF 测试可以在单行中执行,但也可以像其他语句一样用来控制代码块。

真或假

[编辑 | 编辑源代码]

布尔逻辑是一种测试,它只产生两种可能的结果之一,真或假。测试本质上始终是数学上的……当两个字符(或字符串)“比较”时,使用的是它们的 ASCII 码(因此 a < b 且 b < A)。

在 QBasic 中使用的比较运算符为:= 如果两个变量相等则为真 < 如果第一个小于第二个则为真 =< 如果第一个小于或等于第二个则为真 > 如果第一个大于第二个则为真 >= 如果第一个大于或等于第二个则为真 <> 如果两个不相等则为真

可以使用“AND”、“OR”和“NOT”运算符将多个测试链接在一起。我们将在后面详细介绍这些运算符的含义,但您可能已经理解前两个运算符了。

QBasic 中最有用的语句之一是 IF 语句。它允许您根据给定的条件选择程序将执行的操作。接下来的几个程序将介绍一些使用 IF 语句的方法。

IF [conditional] THEN [do this]

单行 IF 是最简单的示例。要执行代码块,使用 END IF

 IF [conditional] THEN
   [do this]
   [and do this]
    ...
   [and also do this]
 END IF

IF...THEN...ELSE

[编辑 | 编辑源代码]
IF [conditional] THEN [do this] ELSE [do that]

要从两个不同的代码块中选择,使用 ELSE 语句。

IF [conditional] THEN
  [do this]
  ..
  [and do this]
ELSE
  [do that]
  ..
  [and also that]
END IF

13 ELSEIF

[编辑 | 编辑源代码]

作为从头开始一个全新的 IF THEN ELSE 语句序列的替代方案。您可以在 THEN 语句(s)之后添加 ELSEIF [条件] THEN。这不会创建新的嵌套级别。

IF [条件] THEN

 [do this]
 ..
 [and do this]

ELSEIF [条件] THEN

 [do that]
 ..
 [and also that]

ELSEIF [条件] THEN

 [do the other]
 ..
 [and also ...]

ELSE

 [do this final thing]

END IF

FOR...NEXT

[编辑 | 编辑源代码]
FOR <variable name> = <start value> TO <end value> [STEP <increment>]
 [do this]
 ...
 [and do this]
NEXT

<增量> 可以是 + 或 -,并且是可选的。如果省略,默认值为 +1。FOR 循环中包含的代码始终至少执行一次,因为只有在 'NEXT' 语句处才会检查变量的值是否超过结束值。

当 NEXT 语句执行时,变量将根据 STEP 值进行修改,并与结束值进行比较。如果变量尚未超过结束值,控制权将返回到 FOR 语句后的行。

您可以使用 EXIT FOR 命令提前退出 FOR 循环。

14FOR.BAS

[编辑 | 编辑源代码]
 CLS
 RANDOMIZE TIMER

 num = INT(RND * 20) + 1

 FOR count = 1 TO 5
  INPUT "Pick a number between 1 and 20: ", answer
  IF answer = num THEN PRINT "You win after";count;"guesses!": END
 NEXT
 PRINT "You lose"

WHILE...WEND

[编辑 | 编辑源代码]
 WHILE <condition is true>
   [do this]
   ..
   [and this]
 WEND

如果条件为真,则执行 WHILE 语句后的代码。当执行 WEND 命令时,它将控制权返回给 WHILE 语句(在那里再次测试条件)。当条件计算为 FALSE 时,控制权将传递到 WEND 语句后的语句。

15WHILE.BAS

[编辑 | 编辑源代码]
PRINT "Press any key to continue"
WHILE INKEY$=""
WEND

在上面的例子中,您看到了一个“按任意键继续”的提示,它会等待用户按下任何键。(INKEY$ 功能将在 高级输入 中介绍。)


DO...LOOP

[edit | edit source]
 DO
   [this]
   ..
   [and this]
 LOOP WHILE <condition is true> / LOOP UNTIL <condition is true>

DO...LOOP 结构是 WHILE 循环的更高级形式 - 与其他流程控制块一样,它由 DOLOOP 标记以表示边界。

它依赖于放置在 DO 或 LOOP 后的条件语句。

DO
  a$ = inkey$
LOOP WHILE a$=""

作为替代方案,您可以用 UNTIL 替换 WHILE,让循环在满足特定条件之前继续。

DO
  x=x+1
LOOP UNTIL x >= 10

在某些版本的 BASIC 中,UNTIL 或 WHILE 条件可以跟随 DO 语句而不是 LOOP 语句(前测),与上面显示的(后测)相反。

12IF.BAS

[edit | edit source]
 CLS
 RANDOMIZE TIMER

 num = INT(RND * 100) + 1
 DO 
      INPUT "Pick a number between 1 and 100: ", answer

      IF num = answer THEN PRINT "You Got It!"
      IF num > answer THEN PRINT "Too Small"
      IF num < answer THEN PRINT "Too big"
LOOP UNTIL num = answer
PRINT "Game Over."

SELECT CASE

[edit | edit source]
 SELECT CASE <variable expression>
   CASE <value>
     [do this]
   CASE <value 2>
     [do instead]
   ...
   CASE ELSE
   ...
 END SELECT

select 语句是重复使用 IF 语句的替代方法。<变量表达式> 被计算并依次与每个 CASE <值> 进行比较。当找到与 CASE <值> 匹配的值时,将执行后面的 [do this] 代码。如果执行了 EXIT CASE,控制权将传递到 END SELECT 后的行,否则将检查下一个 CASE <值>。如果未找到匹配项,则执行 CASE ELSE。请注意,<值> 可以是数字、字符或字符串或逻辑表达式(例如 '>0'、'<>1')。还要注意,可能会找到并执行多个 CASE 匹配(因此,例如,如果两个 CASE <值> 是 'CASE >1' 和 'CASE >10',一个计算结果为 11(或更多)的 <变量表达式> 将导致 CASE >1 和 CASE >10 都被执行)。

CLS
PRINT "WELCOME"
PRINT "I HAVE AN ANSWER FOR ANY OF YOUR QUESTIONS"
10 INPUT "WRITE YOUR QUESTION AND I'LL GIVE YOU AN ANSWER ", question$
RANDOMIZE TIMER
PRINT
answer = INT(RND * 4 + 1)
SELECT CASE answer
    CASE 1
        PRINT "PLEASE REPHRASE YOUR QUESTION."
    CASE 2
        PRINT "YOUR QUESTION IS MEANINGLESS."
    CASE 3
        PRINT "DO YOU THINK I CAN ANSWER THIS?"
    CASE 4
        PRINT "THIS QUESTION LOOKS FUNNY."
END SELECT
PRINT
PRINT "ENTER ANOTHER QUESTION", K$
GOTO 10

如果一个参数会被多个 case 语句覆盖,第一个选项将优先考虑。

高级输入

[edit | edit source]

INKEY$

[edit | edit source]

从用户那里获取实时信息有点困难。为此,我们将使用 INKEY$ 命令,它会检查用户是否键入了一个键,并将该键压送到程序中。

看看这段代码,然后我们将深入了解它。

DO
	LET k$ = INKEY$
LOOP UNTIL k$ <> ""
SELECT CASE k$
	CASE "q"
		QuitProgram
	CASE "c"
		MakeCircle
	CASE "s"
		MakeSquare
END SELECT

第一部分是 DO-LOOP,它不断轮询 INKEY$ 以获取返回值。在基本用法中,如果没有任何键被按下,INKEY$ 会返回一个空字符串,并继续执行程序。一旦按下键,INKEY$ 会立即返回该键。

键盘缓冲区

[edit | edit source]

INKEY$ 在做什么,它是怎么工作的呢?

虽然 INKEY$ 命令看起来像返回当前按下的键,但事实并非如此。它被程序用来回答“KEYboard 缓冲区中有什么?”这个问题。要理解这一点,您需要理解什么是基本的缓冲区,以及为什么使用它。

在旧的系统中(不一定是指 IBM PC),一个单一的芯片处理键盘输入,并控制 Caps Lock 和 Num Lock 的 LED 灯。由于计算机一次可以做很多事情(例如,从鼠标获取输入,处理数字,调用子例程,在屏幕上显示新信息),因此它需要能够记住在它忙于其他工作时键盘上按了什么键。该芯片包含了一些内存(称为缓冲区),用于跟踪有限数量的键压。

在 IBM PC 的 Dos 平台下,硬件略有改变。在硬件缓冲区中,按下或释放一个键会中断正在运行的程序,以将一个键击添加到位于 BIOS 中的软件缓冲区中。这个过程通常是用户没有意识到的,对系统性能的影响很小。但是,这个缓冲区允许 15 个字符:当计算机繁忙时试图溢出它会导致短暂的蜂鸣声,并且会丢弃任何后续的字符。

INKEY$ 命令将此缓冲区用作 FIFO(先进先出)缓冲区。举个例子,假设您有一个游戏,屏幕上有一个弹跳球,底部有一个挡板。计算机程序必须不断更新屏幕以显示球的运动。在执行此操作时,程序会经过一个 INKEY$ 命令来查看返回的值。如果用户自上次调用该命令以来按下了某个键,它将返回该键。假设球正在向右移动,用户需要按 “R” 键告诉程序将挡板向右移动。由于程序忙于移动球并更新屏幕,因此它不会立即注意到用户按下了该键。相反,键压将存储在键盘缓冲区中,并在几毫秒(或微秒)后,当 INKEY$ 命令被使用时被检索。

在许多程序中(如上所述),INKEY$ 将出现在循环中。它被反复请求。这使得程序可以一次获取一个字符的用户输入。使用我们上面的例子,用户可能需要反复按下 R,直到挡板在球的下方。另一方面,用户可能按了太多次 R,需要按 L 将其向左移动。由于 INKEY$ 命令使用的是 FIFO 缓冲区,因此它将始终按照用户输入的顺序检索按下的键。

总而言之,INKEY$ 命令始终会返回并删除键盘缓冲区中的第一个字符。一般来说,它被反复使用以检索所有按下的键,并允许用户以接近“实时”的方式与程序交互。如果键盘缓冲区中没有键,INKEY$ 会返回一个空字符串(无字符)。

扫描码

[edit | edit source]

有些键压与 ASCII 字符没有关联。当按下这些键之一时,INKEY$ 返回一个包含两个字符的字符串:第一个字符是空字符(ASCII 码 0),第二个是键盘的原始扫描码。扫描码的完整列表可以在 QBASIC 帮助文件中找到。您也可以通过检查按下这些键时 INKEY$ 的结果来确定扫描码。

注意
某些键无法通过 INKEY$ 直接检测到。

  Ctrl+            Extended; prefixed with CHR$(0)
 1  A               3   Ctrl+2
 2  B              15   Shift+Tab
 3  C              
 4  D                Alt+    Alt+    Alt+     Alt+
 5  E              16  Q   30  A   44  Z   120  1
 6  F              17  W   31  S   45  X   121  2
 7  G              18  E   32  D   46  C   122  3
 8  H  Backspace   19  R   33  F   47  V   123  4
 9  I  Tab         20  T   34  G   48  B   124  5
10  J  Ctrl+Enter  21  Y   35  H   49  N   125  6
11  K              22  U   36  J   50  M   126  7
12  L              23  I   37  K           127  8
13  M  Enter       24  O   38  L           128  9
14  N              25  P                   129  0
15  O                                      130  -
16  P                 Shift Ctrl Alt       131  =
17  Q              59   84   94  104  F1
18  R              60   85   95  105  F2
19  S              61   86   96  106  F3
20  T              62   87   97  107  F4
21  U              63   88   98  108  F5
22  V              64   89   99  109  F6
23  W              65   90  100  110  F7
24  X              66   91  101  111  F8
25  Y              67   92  102  112  F9
26  Z              68   93  103  113  F10
27  [  Escape     133  135  137  139  F11
28  \             134  136  138  140  F12
29  ]
30  6              71  Home   72  Up    73  PgUp
31  -              75  Left             77  Right
                   79  End    80  Down  81  PgDn
   Ctrl+           82  Insert           83  Del
127 Backspace
                  119  Ctrl+Home   132  Ctrl+PgUp
                  115  Ctrl+Left   116  Ctrl+Right
                  117  Ctrl+End    118  Ctrl+PgDn

子例程和函数

[edit | edit source]

目的

[edit | edit source]

子例程和函数是将代码分解成可重用“块”的方法。它们允许程序员通过调用相应的过程或函数来重用一组通用的指令。

例如,假设您需要打印多个值表。一种方法是直接将所有表 PRINT 命令输入到您需要它们的位置。但是,这不仅会使程序非常大,而且还会使调试或更改表“样式”变得更加困难。更简单的方法是创建一个单一的“打印表”过程,并将所有 PRINT 命令输入到其中。然后,每当您需要打印表格时,您只需使用要打印的值列表“调用” “打印表”过程即可。

过程 vs. 函数

[edit | edit source]

过程会执行某些操作,但不会为程序员返回任何值。例如,过程可能用于设置屏幕模式和调色板。

函数会执行某些操作并返回一个值。例如,如果您需要找到两个值的平均值,您可以编写一个函数,该函数接收两个数字并返回平均值。

GOTO 和 GOSUB

[edit | edit source]

GOTO 和 GOSUB 语句是最初创建子程序的方法。它们在较旧的 BASIC 实现中最为常见,并出于兼容性原因保留了下来;但是,不建议在其他编程语言或大型项目中使用它们,因为 GOTO 使“跟踪”程序流程变得更加困难,而 GOSUB 不会“隔离”对任何变量所做的更改。

这两个命令依赖于标签,标签有两种形式。第一种也是较旧的形式是在每一行开头编写行号(通常以 10 为增量)。较新的方法类似于其他编程语言,即一个单词后跟一个冒号。

GOTO 语句很简单;它只是将执行点移至给定的标签。

GOSUB 语句将控制权转移到给定的标签,但是当遇到 RETURN 语句时,执行将返回到 GOSUB 语句后的下一行。在 GOSUB 中所做的任何更改都将反映到“主”代码中使用的实际变量中。

ON ERROR 允许您为程序定义错误处理程序;当发生错误时,它会立即跳转到给定的标签。程序到达 RESUME 语句后,控制权将返回,该语句可以将控制权返回到同一位置、下一条语句或任何其他所需标签。

在 Qbasic 中,错误处理程序不能位于任何子程序中。因此,任何错误检查或标志都必须通过使用与主模块共享的变量来处理。

注意
虽然 QBasic 文档指出 ON ERROR RESUME NEXT 是一个有效的语句,但这不正确。

注意:如果您的错误处理例程中没有“resume”语句(即您尝试使用 gotos 来完成所有操作),则错误处理只会工作一次 - 下一个“on error”将被忽略,并且程序将结束,就像您根本没有“on error”语句一样。此问题似乎没有在任何文档中提及。我花了三个小时才弄清楚为什么两个几乎相同的程序部分的行为如此不同。

声明子程序

[编辑 | 编辑源代码]

声明子程序的更佳方法是使用 SUB 语句块,因为(默认情况下)在退出时会丢弃在子程序中使用的任何新变量。

在 QBasic IDE 中,这样做会将 SUB 块移动到它自己的窗口中,以防止意外删除模块,并使程序代码更容易组织。

调用子程序就像编写子程序的名称(传递任何必需的参数)一样简单。如果需要,可以使用 CALL 语句来向其他程序员表明它是一个子程序。

SUB name (params)
{SHARED variables 'if any}
'{code to execute}
'  ...
'  ...
{STATIC variables 'if any, to be saved for use next time}
END SUB

虽然传递给子程序的参数是按“引用”传递的(即它们在 SUB 中使用新名称),但对值所做的任何更改都会“反映回”原始值。默认情况下,在达到 END SUB 时(或执行 EXIT SUB 时)会丢弃在 SUB 中使用的所有其他变量,除非如下所述:

要在下一个 CALL 中“保留”在 SUB 中使用的变量的值以供重复使用,请在最后使用 STATIC 关键字。

如果您需要访问一个变量(未作为参数传递),请使用 SHARED 关键字在子程序的开头定义它(共享变量保留其名称)。

声明函数

[编辑 | 编辑源代码]

函数是一种返回值的子程序形式。定义子程序中所适用的一切也适用于函数。在函数中,返回值是通过将函数名用作变量来创建的 - 当达到有效的退出或结束调用时,返回值将传递给调用表达式。有两种方法可以从函数中返回,一种是到达 END FUNCTION 语句,另一种是调用 EXIT FUNCTION。END FUNCTION 和 EXIT FUNCTION 之间的区别在于,只能有一个 END FUNCTION,并且它必须出现在函数的所有其他代码之后,因为它表示代码块的结束。EXIT FUNCTION 可以出现多次,并且可以放置在任何认为合适的地方。

FUNCTION name (params) 
  ' Shared variable declarations
  name = result
  ' ...
END FUNCTION

函数的声明方式与变量相同 - 它返回它定义为返回的变量类型,与变量定义为包含其指定类型的方式相同。默认情况下,它是数字,但附加一个美元符号表示它返回一个字符串。

函数只能在表达式中调用;与子程序不同,它们不是独立的语句。

数组和类型

[编辑 | 编辑源代码]

内置类型

[编辑 | 编辑源代码]

QBasic 有五种内置类型:INTEGER (%)、LONG (&) 整数、SINGLE (!) 浮点数、DOUBLE (#) 浮点数和 STRING ($)。QB64 还有两种内置类型:_INTEGER64 (&&) 和 _FLOAT (##)

隐式声明是通过在变量名称末尾添加类型字符来完成的(%、&、!、#、$、&&、##)。有关更多信息,请参见 QBasic/Basic Math

显式声明是通过在第一次使用之前使用 DIM 语句来完成的。

DIM a AS STRING
DIM b AS INTEGER
DIM c AS LONG
DIM d AS SINGLE
DIM e AS DOUBLE
DIM f AS _INTEGER64 'QB64 only
DIM g AS _FLOAT 'QB64 only

如果您不使用隐式或显式声明,则 QBASIC 解释器会假设 SINGLE 类型。

用户定义类型

[编辑 | 编辑源代码]

用户定义类型允许您创建自己的数据结构。请注意,自定义类型类似于数组。

 TYPE playertype
  name AS STRING
  score AS INTEGER
 END TYPE

然后,您可以根据此类型声明变量,并访问它们。

DIM playername AS playertype
playername.name = "Bob"
playername.score = 92

上面的示例展示了如何将自定义类型用于维护数据,例如在玩游戏的玩家身上。

数组是在单个变量中存储的值的集合。STRING 是字符的数组(因此,例如,char$(1) 表示字符串 char$ 中的第一个字符)。数字数组应使用 DIM 指令定义(除非您定义它们,否则它们在每个维度上都限制为 10 个元素)。

默认情况下,QBasic 中的数组大小是静态的,不能在程序的后续部分更改。设置此类数组的代码如下所示:

DIM myArray(10) as TYPE 'this is explaining the datatype to be used during program execution in array'

TYPE 可以是任何内置的 QBasic(INTEGER、LONG、SINGLE、DOUBLE、STRING)或用户定义的类型。如果没有指定,则数组将采用由变量名称后缀定义的类型 - INTEGER (%)、LONG (&) 整数、SINGLE (!) 浮点数、DOUBLE (#)、STRING ($) - 或者如果没有,则为 INTEGER。

警告:如果您的数据类型是字符串,则 DIM string(10) 定义一个包含 10 个字符的单个字符串,而不是 10 个任意长度的字符串!(10 个最多包含 128 个字符的字符串将被定义为 DIM string(10,128)

通过在程序开头发出元命令 '$DYNAMIC,您可以使数组变为动态的

 ' $DYNAMIC
 DIM myDynamicArray(5) as INTEGER
 REDIM myDynamicArray(10) as INTEGER

现在这段代码是完全合法的。

要释放数组占用的空间,请使用 ERASE 语句。

多维数组

[编辑 | 编辑源代码]

数组不限于一个维度 - 可以声明一个数组来接受两个参数,以表示值网格。

 DIM housenames(25,25) as STRING

您不能使用 REDIM 语句来更改数组的维度数,即使使用动态分配也是如此。

非零基

[编辑 | 编辑源代码]

在大多数语言中,数组从值 0 开始,并向上计数。在 basic 中,可以索引数组,使它们从任何值开始,并以任何其他值结束。

 DIM deltas(-5 TO 5)

您可以使用 OPTION BASE 语句更改默认的下界。

在本课中,我们将学习如何创建和修改文件。在这样做的过程中,我们将创建一个文本编辑器的部分内容来处理读写磁盘上的文件 - 该程序在本节结束时不会完成,而是在高级文本输出中完成。

让我们从设置主程序开始

'$DYNAMIC
ON ERROR GOTO handler ' Prepares the error handler
DIM text(50) AS STRING ' Used to contain the text file.
maxlines = 50 ' Contains the current size of the buffer.

DO
  CLS 'clears the screen
  INPUT "Would you like to create a (N)ew file, (L)oad an existing one, or (E)xit the program"; choice$

  SELECT CASE UCASE$(choice$) 'UCASE$ converts strings to UPPER CASE
    CASE "N" 'New file
    CASE "L" 'Load a file
    CASE "E" 'Exit
      CLS
      END
  END SELECT
LOOP 'returns to the top of the program.

handler:
errorflag = ERR  ' Keep track of the error that occurred.
RESUME NEXT ' Proceeds with the next statement.

如您所见,我们正在使用CASE而不是IF. IF语句有时比 case 语句更有效,但现在,我们想要避免意大利面条代码(其中有太多GOTO's)。

到目前为止,我们还没有太多内容,但这只是一个开始。我们已经询问了用户他们想做什么,并完成了 1/3 的选项。从这个角度来说,还不错!

OPEN 语句

[编辑 | 编辑源代码]

OPEN 语句允许从磁盘读取或写入信息。通常,OPEN 语句遵循以下模式

OPEN file$ FOR INPUT AS 1
OPEN file$ FOR OUTPUT AS 2

文件$确定要使用的文件名。该FOR部分指示如何访问或操作文件 - 它可以是 APPEND、BINARY、INPUT、OUTPUT 和 RANDOM。该AS #是用于该文件句柄的标识符 - 如果需要,它可以是一个变量。

注意
如果你允许用户输入磁盘上不存在的文件名,你需要使用ON ERROR来处理这种情况。

输入和输出

[编辑 | 编辑源代码]

当你需要访问或写入文件句柄的内容时,PRINT 和 INPUT 语句需要文件句柄作为第一个参数

 INPUT #1, a$
 PRINT #2, a$

在某些情况下,你需要检测是否将要到达文件末尾 - 这是由 EOF 函数执行的,它接受一个接收输入的文件句柄。

从磁盘读取文件

[编辑 | 编辑源代码]

我们现在将添加一个子例程,以从磁盘读取完整文件,作为文本行,放入一个名为 text() 的字符串数组中。也可以读取一个包含数值的 data 文件(并将这些值输入到一个数字数组中),但这属于另一个主题。

请注意,通过逐行读取直到文件末尾,查找文件 'size' 的代码,以及使用 'SEEK' 来 '回绕' 到开头。

SUB LoadFile
  SHARED filename$
  SHARED lines, maxlines
  SHARED text() AS STRING
  SHARED errorflag
    
  INPUT "Enter filename: "; filename$

  OPEN filename$ FOR INPUT AS 1
  IF errorflag <> 0 THEN
    errorflag = 0
    CLOSE
    PRINT "File not found - press return to continue."
    INPUT "", a$
    EXIT SUB
  END IF

  ' Count the number of lines.
  lines = 0
  DO WHILE NOT EOF(1)
    LINE INPUT #1, l$
    lines = lines + 1
  LOOP

  'Allocate enough space for input. 
  IF maxlines > lines THEN
    REDIM text(lines + 25) AS STRING
    maxlines = lines + 25
  END IF
  SEEK #1, 1 ' Rewind to the beginning of the file.

  ' Read the lines into the buffer
  FOR cline = 1 TO lines
    LINE INPUT #1, text(cline)
  NEXT
  CLOSE 1
  errorflag = 0

END SUB

上面的示例将文件视为 type=text。如果文件包含数字(例如,每行 N 个整数 x M 行的数据数组),则可以一次读取一个数字(input #),直接输入到数字数组中。Input 将一次读取一个数字,在每个数字输入后 '停止'。数字可以用 '任何东西' 分隔(因此文本行将被跳过)。

将文件写入磁盘

[编辑 | 编辑源代码]

用于将文件写入磁盘的函数更简单

SUB SaveFile (outfile$)
  SHARED filename$
  SHARED lines, maxlines
  SHARED text() AS STRING
  SHARED errorflag
  
  IF outfile$ = "" THEN
    LOCATE 1, 1
    INPUT "Enter filename: "; outfile$
  END IF

  OPEN outfile$ FOR OUTPUT AS 1
  IF errorflag <> 0 THEN
    errorflag = 0
    CLOSE
    PRINT "Couldn't save file - press return to continue."
    INPUT "", a$
    EXIT SUB
  END IF

  ' Write each line to the file
  FOR cline = 1 TO lines
    PRINT #1, text(cline)
  NEXT

  CLOSE 1
  errorflag = 0
  filename$ = outfile$

END SUB

为了创建一个新文件,你必须以 OUTPUT 模式打开它,然后关闭它。示例

OPEN NEWFILE FOR OUTPUT AS #1
CLOSE #1

**注意:** 如果你不小心打开了现有文件,它的所有内容都将被覆盖!

高级文本输出

[编辑 | 编辑源代码]

光标操作

[编辑 | 编辑源代码]

当你尝试编写你的文本编辑器时,你可能会意识到你需要将光标放置在屏幕上的特定位置。这是使用LOCATE语句。

注意
在屏幕的右下角打印任何字符都将导致显示滚动。

要更改当前打印颜色,请使用COLOR语句。

  COLOR 7,0  'Uses the default white on black.
  COLOR 15,0 'Bright white on black.
  COLOR 0,1  'Black on blue
  COLOR 14,0 'Bright yellow.

这可以用于底部标题栏或状态栏。

格式化打印

[编辑 | 编辑源代码]

文件PRINT USING语句允许你以指定格式输出字符串或数字。使用此语句,你可以将数字写入指定的小数位数或执行高级输出。

最常见的格式说明符是#.,它们分别为数字和小数点保留空间。你也可以使用下划线来确保打印某个字符的字面意义。

注意:**PRINT USING** 无法为数字添加*前导零*。例如,如果你指定 3 位数字 (###),两位数将以前导空格输出。

文本动画

[编辑 | 编辑源代码]

在执行特定过程之前,你需要一些时间。通常,最好在过程中制作一个动画,表明程序没有挂起,而是在继续。为什么要用非常复杂的图形来制作?使用这个:<syntaxhighlight lang = QBasic> SUB TEXT_ANIM

   X = 15 ' CAN BE ANY OTHER VALUE TOO
   Y = 15 ' CAN BE ANY OTHER VALUE
   LOCATE Y,X 
   DO
       PRINT ">     "
       SLEEP 1
       CLS
       PRINT " >    "
       SLEEP 1
       CLS
       PRINT "  >   "
       SLEEP 1
       CLS
       PRINT "   >  "
       SLEEP 1
       CLS
       PRINT "    > "
       SLEEP 1
       CLS
       PRINT "     >"
       SLEEP 1
       CLS 
    LOOP UNTIL INKEY$ <> ""

END SUB </SOURCE> 该程序使用 **INKEY$**,你还没有学习过,以及 **SLEEP** 和 **DO...LOOP**,你也没有学习过。有关更多信息,请参阅流程控制附录

QBasic 有三种发出声音的方式。

  • BEEP 命令
  • SOUND 命令
  • PLAY 命令

以前用作 PRINT CHR$(07),现在可用的 BEEP 命令会发出蜂鸣声。它通常用于在显示某些重要消息时吸引注意。

'Syntax example
BEEP 
PRINT CHR$(07)

这两个命令,正如在计算机上运行此程序可以看出,完全相同。


SOUND 命令从 PC 扬声器产生特定频率的特定持续时间的音调。一次只能播放一个音调。如果连续发出多个 SOUND 语句,第一个语句之后的每个语句都不会执行,直到之前的语句完成。

SOUND f, d
  • f - 频率,单位为赫兹,范围为 37 到 32767
  • d - 持续时间,单位为刻度,范围为 0 到 65535,每秒 18.2 个刻度
SOUND 100, 18.2

播放 100 赫兹波形,持续 18.2 个刻度,约 1 秒。

QBasic 允许的最低频率是 37 Hz,这大约是第 2 个八度的 D 音。最高频率是 32 767 Hz,但此音调无法听到,因为正常人的听力范围在 20 000 Hz 结束。

SOUND 命令的另一个功能是使用它来控制程序中的时间。

   For x% = 1 TO 10
    Print x%
    Sound 3200,18.2
   NEXT

此程序将打印数字 1 到 10,每个数字之间延迟 1 秒,并播放 3200 赫兹的音调,间隔 1 秒。(由 FalcoN 编辑)

PLAY 命令用于播放乐音,八度。它一次只能播放一个音符。

除此之外,play 命令可以播放复杂的存储的 "歌曲"。这是通过使用歌曲字符串实现的。有关字符串命令的详细信息,请参阅QBasic/附录#PLAY

Qbasic 中的简单音乐键盘

[编辑 | 编辑源代码]
rem Music keyboard
do 
note$ = inkey$
select case ucase$(note$)
case "A"
Play "A"

case "B"
Play "B"

case "C"
Play "C"

case "D"
Play "D"

case "E"
Play "E"

case "F"
Play "F"

case "G"
Play "G"

end select 

loop until ucase$(note$) = "Q"

end

这段代码使用了一个选择情况命令来检查 note$ 的值。Ucase$ 用于确保无论 Caps Lock 是否开启,都不会有区别。play 命令用于播放不同的音符。这里没有使用 play 的其他功能。

QBasic 在图形方面能做什么

[编辑 | 编辑源代码]

QBasic 在图形方面能力有限,但可以用它创建许多优秀的程序。PSET、CIRCLE、LINE 等命令用于在 QBasic 中绘制图形。使用 QBasic 创建的图形程序的优秀例子是 **对称图标** 和 **对称分形**。

Screen 将允许你设置它的使用方式。文本图形、两者兼有,以及你正在处理的表面的大小。Screen 0 .. 表示仅文本。Screen 12 .. 表示 64 X 480 X 16 色 & 文本。

PSET 命令允许程序员在屏幕上显示像素。在输入命令之前,必须确保 SCREEN 命令已存在。请看这个例子

SCREEN 13
PSET (1,1), 43

此命令将在坐标 1, 1 处显示一个黄色像素。坐标是 X 和 Y 坐标,与任何其他数学情况一样。因此 PSET 命令必须具有这种布局才能正常工作

PSET ([X coordinate], [Y coordinate]), [Colour of Pixel]

请记住,X 坐标是在屏幕上从左到右的坐标,Y 坐标是在屏幕上从上到下的坐标。

   LINE [[STEP](x1!,y1!)]-[STEP](x2!,y2!) [,[color%] [,[B | BF] [,style%]]]
   STEP          Specifies that coordinates are relative to the current
                   graphics cursor position.
   (x1!,y1!),    The screen coordinates of the start of the line and of
   (x2!,y2!)     the end of the line.
   color%        A color attribute that sets the color of the line or
                   rectangle. The available color attributes depend on your
                   graphics adapter and the screen mode set by the most
                   recent SCREEN statement.
   B             Draws a rectangle instead of a line.
   BF            Draws a filled box.
   style%        A 16-bit value whose bits set whether or not pixels are
                   drawn. Use to draw dashed or dotted lines.

这个简单的程序显示一条线

  Screen 13 
  LINE (160,10)-(100,50),13 
Simple Line
简单的线
CIRCLE (100, 100), 25, 4,0,3.14

这将在坐标处显示一个圆圈。该函数的布局如下

CIRCLE ([X Coordinate], [Y Coordinate]), [Radius], [Colour Number],[Start Angle],[Finish Angle]

请记住在前面添加一个 SCREEN 命令。

要使用 PAINT,必须声明一个 SCREEN 命令。该命令具有告诉 QBasic 从哪里开始的坐标。颜色编号指定要使用的颜色,而边框颜色告诉 PAINT 命令当它遇到该颜色的像素时不要再绘制。在几乎所有情况下,你都需要使用边框颜色参数,仅仅是因为没有它,PAINT 将覆盖整个屏幕。

PAINT ([X Coordinate],[Y Coordinate]), [Color Number], [Border Color]1,2,3,4,5,5

待办事项

使用 DATA 命令制作图像

[编辑 | 编辑源代码]

使用此命令创建的图形可以通过使用图形编辑器或手动使用 DATA 命令来创建。DATA 命令是将信息输入 QBasic 并由 READ 命令读取的一种方式。请记住,DATA 命令不能在子例程或函数中使用。请看这个例子

SCREEN 7
FOR y = 1 TO 10
FOR x = 1 TO 10
READ z
PSET (x, y), z
NEXT
NEXT
DATA 04, 04, 04, 04, 04, 04, 04, 04, 04, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 00, 00, 00, 00, 00, 00, 00, 00, 04
DATA 04, 04, 04, 04, 04, 04, 04, 04, 04, 04

FOR 命令声明要读取的像素数量。在这个特定的程序中,有 10 x 10(100)个像素,所以我们输入

FOR x = 1 TO 10
FOR y = 1 TO 10

我们现在已经声明了 x 和 y 平面。如果你想要更小或更大的位图,你可以更改这些值。READ 命令读取 DATA 命令并将收集到的信息声明为 z。

READ z

PSET 读取平面和 DATA 读取,并生成位图。

PSET (x, y), z

它的工作原理类似于本页的第一个示例,只是它读取了多个像素

高级图形

[编辑 | 编辑源代码]

基本移动

[编辑 | 编辑源代码]

动画基本上是在固定时间段内变化的图形。这里我们将使用一个 do-loop。

SCREEN 7  ' we need to use a graphics enabled screen mode
animation   'calling the sub


SUB animation
    SCREEN 7
    x = 10 'set first x- coordinate
    y = 10 'set first y-coordinate
    DO
        CLS ' going back to a blank screen so that the previous rectangle is erased
        x = x + 3  ' setting increment of coordinate x
        y = y + 3   ' setting increment of coordinate y

        LINE (x, y)-(x + 5, y) 'drawing lines
        LINE (x, y + 5)-(x + 5, y + 5)
        LINE (x, y)-(x, y + 5)
        LINE (x + 5, y)-(x + 5, y + 5)

        SLEEP 2

    LOOP UNTIL INKEY$ <> ""



END SUB

解释

  1. 我们已从默认的 Qbasic 仅文本屏幕切换到启用图形的屏幕。
  2. 我们已调用创建动画的子程序。
  3. 我们已开始 do-loop 直到。这使动画能够运行,直到用户按下一个键结束它。
  4. 我们已设置坐标的增量。这使得方框可以在新的位置而不是同一个位置绘制。如果希望它只在一个方向上移动,我们只需要在一个变量中设置增量。
  5. 我们已从每个坐标绘制到另一个坐标的线条。请注意,每次一个坐标保持固定,而其他坐标会改变。(这里我指的是两个坐标集,第一个是起始坐标,第二个是结束坐标)
  6. 我们已发出一个 sleep 命令。这会停止执行 2 秒。如果没有它,do-loop 会比我们想要的更快执行,动画会很短暂。
  7. 通过对变量使用 RND,你可以创建随机的、不可预测的动画。


鼠标控制

[编辑 | 编辑源代码]

在此步骤中,我们将使用 QB64 内置的 _mousehide、_mousex、_mousey、_mouseinput 和 _mousebutton 命令来控制鼠标输入。

These Functions only work in QB64!
_mousehide
screen 7

mousetrack

sub mousetrack
do while _mouseinput
cls

X = _mousex
Y = _mousey

LINE (X - 10, Y)-(X + 10, Y), 15
LINE (X, Y - 10)-(X, Y + 10), 15

        IF _MOUSEBUTTON(1) THEN
            IF X > A AND X < A + 25 AND Y > B AND Y < B + 25 THEN
                message$ = "yes"
                goto action
            END IF
        END IF

loop until inkey$ <> ""
  1. 这里第一个函数 "_mousehide" 阻止默认的指针鼠标格式显示在屏幕上
  2. Mouseinput 函数检索鼠标信息。
  3. 接下来的函数 "_mousex" 和 "_mousey" 包含鼠标的当前 x 和 y 坐标。
  4. 这些行绘制了一个基本的触发器。
  5. "_mousebutton" 函数返回所按鼠标按钮的值,“1” 表示按下了左键。
  6. 如果鼠标按钮事件发生在某个封闭区域内,则会发出“message$”形式的消息。这可以稍后使用。
  7. 如果满足了前面的条件,则过程会转到行标签“action”,这里可能包含要执行的任何命令。
  8. 否则,该过程会循环,直到满足“循环直到”条件。它也可以是除上面给出的条件以外的其他条件。

这些图形和动画可用于创建一个完整的游戏。你可以使用“Inkey$”命令而不是“鼠标”函数来发出各种场景和情况,每种情况都有一个完整的代码来决定接下来发生什么。

你可以使用“.txt”文件来存储信息,而不是制作不包含任何用户信息的游戏。这些信息可以稍后检索,用于创建具有完整“职业”选项的游戏。

3D 图形

[编辑 | 编辑源代码]

简单的 3D 盒子

[编辑 | 编辑源代码]

在 Qbasic 中,3 维或 3D 图形只不过是在二维结构中添加一个额外的 'z' 轴,并沿着该轴进行扩展。这可以通过在每次新的 x 和 y 位置绘制一个盒子或所需的结构来实现。这与动画非常相似,只是我们不会在绘制完结构后擦除它,并且不需要任何中间暂停。您可以通过查看下面给出的 3D 盒子程序来更好地理解。

Redo:
cls
screen 1
Input "Enter the X-position?";k  'entering coordinates of the screen from where to start.
Input "Enter the Y-position?";l   ' this also determines the size of the box.
color 1
for i = 1 to 50 step 2   rem box ' step to ensure space between the boxes, make it one to eliminate the space. The 50 number sets the extension of the box along the z axis
    a = k+i:b = l+i          ' this "for-next" loop draws the box over and over again, each with incremented values of k and l.
    line (a,a)-(b,a)
    line (a,b)-(b,b)
    line (a,a)-(a,b)
    line (b,a)-(b,b)
next                            rem diagonals
line (k,k)-(a,a)              ' the four diagonals to the structure , which make it more realistic
line (l,l)-(b,b)
line (l,k)-(b,a)
line (k,l)-(a,b)
Input"Do you want to redo? (Y/N)";ans$
if ucase$(ans$)="Y" then goto Redo
end

除了 QB64 之外的所有 IDE 中,这些函数均无法工作。

简单的图像

[编辑 | 编辑源代码]
rem image_display
cls
Dim Image as long
x = 1000  'resolution
y = 1000
Image = _loadimage("TEST.jpg") 'loading the image
screen _newimage(x,y,32) 'putting screen sizes
_putimage (0,0),Image 'putting image

所以您可能非常期待大量代码。就是这样,您需要在 QB64 中显示图像的所有内容!

那么,这令人惊叹的简单代码究竟做了什么?

逐步解释

  1. 我们已将变量 Image 定义为一个长整型值。这是因为 _loadimage 函数返回的图像句柄是一个长整型值。
  2. x 和 y 是我们的变量。它们保存我们需要设置为分辨率的值。因此,对于 8n00 x 900 的图像,x = 800,y = 900。
  3. 图像变量 Image 接下来被赋予图像“TEST.jpg”的句柄值。一条健康的警告:将图像保存在 QB64 IDE 文件夹中。否则,该函数将无法工作!
  4. 接下来,我们将屏幕调整为适合图像。newimage 函数需要三个参数:分辨率参数和颜色模式参数。这里我们使用 32 位颜色模式,您也可以使用 256 位调色板颜色模式。
  5. 最后,我们使用 _putimage 放置图像,它将 Image 变量(我们的图像句柄)作为其参数。

an example of images in qbasic

_newimage 的辅助用途,用于设置屏幕细节

[编辑 | 编辑源代码]

好吧,您一定在想,所有这些命令都必须以完全相同的顺序使用。不,事实并非如此。您可以单独使用 _newimage 来设置屏幕细节,如下所示

screen _Newimage(1000,1000,256)

此代码将屏幕设置为巨大的 1000 x 1000 分辨率,并使用 256 位调色板颜色模式!

下一步

[编辑 | 编辑源代码]

关于 QBasic 的主题,有很多优秀的网站。以下是最佳网站的列表

Petes QBasic 网站:此网站主要针对那些正在考虑使用 QBasic 编写视频游戏的人。

QBasic 页面:这是一个获取 QBasic 源代码和程序的好网站。

QBasic 新闻:QBasic 社区中最新的最新新闻。

面向儿童的 QBasic 编程:一个适合年轻人开始编程的好网站。

Qb64  : 了解 QB64 的所有内容。

此外,QB64 IDE 具有一个内置的帮助页面,在您不知道如何使用命令时提供必要的帮助。唯一的缺点是,除非您选择命令并右键单击它,然后单击“关于 .... 的帮助”,否则它不会显示任何帮助,这意味着您至少需要在寻求帮助之前知道命令的名称。

进一步编程

[编辑 | 编辑源代码]

如果您正在学习 QBasic,那么您很可能对编程还很陌生。这是一个多样化的世界,探索它!

以下是一些非常好的编程语言,供您进一步学习

示例程序

[编辑 | 编辑源代码]

计算器

[编辑 | 编辑源代码]

此程序可用于非常简单地制作一个简单的、功能正常的计算器。

Rem calculator
cls
10
print "input first operand"
input a
print "select operation"
input b
print "addition(a)"
print "subtraction(s)"
print "multiplication(m)"
print "division(d)"
print "exponentification(e)"
print "rooting(r)"
print "Quit(q)"
do 
next$ = inkey$
loop until next$ <> "" 
gosub input_var2

select case next$
case "a"
c = a + b
print "sum is:";c
case "s"
c = a - b
print "Difference is:";c
case "m"
c= a*b
print "Product is :";c
case "d"
c = a/b
print "Quotient is:";c
case "e"
c = a^b
print "Exponentification is:"c
case "r"
c = a^ 1/b
print "Root is:";c
case "q"
end

end select
sleep 3
goto 10







sub input_var
input "enter second operand";b
end sub

有关参考,请转到 基本数学


基本游戏

[编辑 | 编辑源代码]

使用动画制作一个简单的游戏。

SCREEN 7
COLOR 15, 1


_MOUSEHIDE
CLS
LOCATE 5, 1
PRINT "GUNSHOTS"

DO
    NEXT$ = INKEY$
LOOP UNTIL NEXT$ <> ""

CLS
LOCATE 5, 1
PRINT "In this game, you require to bring"
PRINT ""
PRINT "the crosshairs to the box"
PRINT ""
PRINT " , which is the target ,"
PRINT ""
PRINT " and click to shoot it."
PRINT ""
PRINT " In this game , you control"
PRINT ""
PRINT "the crosshairs with your mouse."
PRINT ""
PRINT " You will be given a"
PRINT ""
PRINT " fixed number of tries."
PRINT ""
PRINT " The number of times you hit the target,"
PRINT ""
PRINT " you will be given a point "

DO
    NEXT$ = INKEY$
LOOP UNTIL NEXT$ <> ""








CLS
LOCATE 5, 1
PRINT "Get Ready!"

DO
    NEXT$ = INKEY$
LOOP UNTIL NEXT$ <> ""




10
A = INT(RND * 100)
B = INT(RND * 100)

DO: K$ = INKEY$
    20

    DO WHILE _MOUSEINPUT
        CLS

        IF TRY_COUNT > 30 THEN
            CLS
            LOCATE 10, 1
            PRINT "Remarks:"
            IF POINT_COUNT < 10 THEN PRINT "OH NO! NICE TRY!"
            IF POINT_COUNT > 10 AND POINT_COUNT < 16 THEN PRINT "GOOD WORK!"
            IF POINT_COUNT > 15 AND POINT_COUNT < 21 THEN PRINT "GREAT!"
            IF POINT_COUNT > 20 AND POINT_COUNT < 26 THEN PRINT "AMAZING!"
            END
        END IF



        SECOND = VAL(RIGHT$(TIME$, 2))
        IF PREVSEC <> SECOND THEN
            COUNT = COUNT + 1
        END IF

        LOCATE 25, 25
        PRINT POINT_COUNT









        X = _MOUSEX: Y = _MOUSEY
        LINE (X - 10, Y)-(X + 10, Y), 15
        LINE (X, Y - 10)-(X, Y + 10), 15

        LINE (A, B)-(A + 25, B), 15
        LINE (A, B + 25)-(A + 25, B + 25), 15
        LINE (A, B)-(A, B + 25), 15
        LINE (A + 25, B)-(A + 25, B + 25), 15
        PAINT (A, B), (1), 15

        IF _MOUSEBUTTON(1) THEN
            IF X > A AND X < A + 25 AND Y > B AND Y < B + 25 THEN
                POINT_COUNT = POINT_COUNT + 1
                TRY_COUNT = TRY_COUNT + 1
                GOTO 10
            END IF


        END IF

        IF COUNT > 1 THEN
            COUNT = 0
            TRY_COUNT = TRY_COUNT + 1
            GOTO 10

        END IF



        PREVSEC = SECOND
        GOTO 20



    LOOP
LOOP

有关参考,请转到 高级图形

一个类似于数字时钟的时钟,没有指针。如果您想使用 draw 制作指针。

REM  Clock
SCREEN 7

CLS
start:
SCREEN 7
_FONT 16
LOCATE 1, 5
PRINT "CLOCK"
PRINT "________________________________________"

LINE (50, 50)-(100, 100), 1, BF
LOCATE 9, 5
PRINT "TIME"
LOCATE 10, 5
PRINT "CONTROL"
LINE (150, 50)-(200, 100), 2, BF
LOCATE 9, 18.5
PRINT "STOP WATCH"



DO

    exit$ = INKEY$
    IF exit$ = "e" OR exit$ = "E" THEN
        CLS
        SCREEN 7
        COLOR 2, 1
        LOCATE 5, 5
        PRINT "YOU HAVE ABORTED THE CLOCK"





        WHILE close_count <> 10
            close_count = close_count + 1
            LOCATE 7, 5
            PRINT "APPLICATION  ";
            IF close_count MOD 2 = 1 THEN
                PRINT "CLOSING >>>   "
            ELSE
                PRINT "CLOSING   >>> "
            END IF




            SLEEP 1
        WEND

        CLS
        SCREEN 7
        COLOR 10, 0
        END
    END IF


    Mouser mx, my, mb
    IF mb THEN
        IF mx >= 50 AND my >= 50 AND mx <= 100 AND my <= 100 THEN 'button down
            DO WHILE mb 'wait for button release
                Mouser mx, my, mb
            LOOP
            'verify mouse still in box area
            IF mx >= 50 AND my >= 50 AND mx <= 100 AND my <= 100 THEN
                GOTO proccess
            END IF
        END IF
    END IF



    Mouser mx, my, mb
    IF mb THEN
        IF mx >= 150 AND my >= 50 AND mx <= 200 AND my <= 100 THEN 'button down
            DO WHILE mb 'wait for button release
                Mouser mx, my, mb
            LOOP
            'verify mouse still in box area
            IF mx >= 150 AND my >= 50 AND mx <= 200 AND my <= 100 THEN
                time_control = 1
                GOTO proccess
            END IF
        END IF
    END IF
LOOP








proccess:

IF time_control = 0 THEN
    time_enter:
    LOCATE 12, 6
    INPUT "enter time"; t
    IF t > 1800 THEN
        mistake = mistake + 1
        IF mistake > 3 THEN
            PRINT "BLOCKED"
            END
        END IF

        GOTO time_enter
    END IF
END IF

Mouser mx, my, mb
IF mb THEN
    IF mx >= 150 AND my >= 50 AND mx <= 200 AND my <= 100 THEN 'button down
        DO WHILE mb 'wait for button release
            Mouser mx, my, mb
        LOOP
        'verify mouse still in box area
        IF mx >= 150 AND my >= 50 AND mx <= 200 AND my <= 100 THEN
            time_control = 1
            GOTO proccess
        END IF
    END IF
END IF



WHILE INKEY$ <> " "
    SLEEP 1
    count = count + 1
    tc = tc + 1
    BEEP
    CLS
    LOCATE 1, 5
    PRINT "CLOCK"
    PRINT "________________________________________"

    IF time_control = 1 THEN
        LINE (150, 50)-(200, 100), 2, BF
    END IF
    LOCATE 3, 5
    PRINT "CURRENT TIME:"; TIME$
    LOCATE 5, 5
    PRINT "MINUTES:"; minute
    LOCATE 6, 5
    PRINT "SECONDS:"; count
    IF count = 60 THEN
        count = 0
        minute = minute + 1
    END IF

    IF time_control = 0 THEN
        LOCATE 8, 5
        PRINT "TIME LEFT:"; (t - tc) \ 60; ":"; (t - tc) MOD 60
        IF tc = t THEN
            BEEP
            BEEP
            BEEP
            BEEP
            END
        END IF
    END IF
    IF time_control = 1 THEN
        Mouser mx, my, mb
        IF mb THEN
            IF mx >= 150 AND my >= 50 AND mx <= 200 AND my <= 100 THEN 'button down
                DO WHILE mb 'wait for button release
                    Mouser mx, my, mb
                LOOP
                'verify mouse still in box area
                IF mx >= 150 AND my >= 50 AND mx <= 200 AND my <= 100 THEN
                    END
                END IF
            END IF
        END IF
        LOCATE 10, 10
        PRINT "PRESS BUTTON TO END"
    END IF

WEND
GOTO start



SUB Mouser (x, y, b)
    mi = _MOUSEINPUT
    b = _MOUSEBUTTON(1)
    x = _MOUSEX
    y = _MOUSEY
END SUB

这是您迄今为止阅读的所有章节的逻辑组合。

二进制编码器

[编辑 | 编辑源代码]

是的,这是一个二进制解码器,但也是一个二进制编码器。它接受任何十进制系统数字,并将其转换为二进制。运行此程序自行查看。

REM binary
SCREEN 7
COLOR 1, 2

_FONT 16
LOCATE 7, 10
PRINT "Binary Coder"

SLEEP 5

start:

CLS
LOCATE 1, 1
PRINT "Binary coder"
PRINT "_____________"
PRINT ""
PRINT ""
PRINT ""
PRINT ""



INPUT "Enter Decimal number"; a
CLS
LOCATE 1, 1
PRINT "Binary coder"
PRINT "_____________"
PRINT ""
PRINT ""
WHILE a <> 0
    PRINT a MOD 2;
    IF a MOD 2 = 1 THEN
        a = a \ 2
    ELSE a = a / 2
    END IF

WEND
PRINT ""
PRINT ""
PRINT "Binary code is reversed"
WHILE INKEY$ <> " "
WEND
GOTO start

唯一的问题是:二进制代码被反转了。您可能已经通过查看最后一个 PRINT 语句猜到了。我仍然没有找到如何反转它的方法,所以我想您必须自己做。并且,WHILE 循环有一个以分号结尾的 print 语句。这用于确保下一个数字出现在它之后,而不是在下一行。

弹道游戏

[编辑 | 编辑源代码]

还记得大猩猩吗?好吧,去掉图形,剩下的就是它。

10
RANDOMIZE TIMER
cor = RND * 150
cor2 = CINT(cor)
IF cor2 < 30 AND cor2 > -30 THEN GOTO 10

PRINT "The object to hit is at coordinates"; cor2

INPUT "enter velocity"; v
INPUT "enter angle"; a
d = ((v ^ 2) * SIN(2 * a)) / 10
PRINT "Hit on:"
PRINT CINT(-d)

IF CINT(-d) < cor2 + 30 AND CINT(-d) > cor2 - 30 THEN
    PRINT "Well Done!"
ELSEIF CINT(-d) < 30 AND CINT(-d) > -30 THEN PRINT "Hey , you hit us!"
ELSE PRINT "Ugh, not on target"
END IF

嗯?好吧,现在数学很复杂,但公式基本上是一样的。在这里,弹丸必须落在撞击物体的 30 个坐标中,否则您就输了。有关数学部分的更多信息,请参阅 维基百科:弹丸运动。提示:添加图形。它将是一个庞大而臃肿的代码,但最终产品将非常棒!

检查听力

[编辑 | 编辑源代码]

好吧,现在,你能听到多高的频率声音?使用此程序测试您的听力。

REM ultrasonic_test
CLS
freq = 20000
DO
    PRINT "Frequency is:"; freq

    SOUND freq, 18.2
    INPUT "Can you hear?"; ans$
    IF ans$ = "no" THEN
        freqrange = freq
        GOTO 10
    END IF
    freq = freq + 100
LOOP
10
freq = freqrange
DO
    PRINT "frequency is:"; freq

    SOUND freq, 18.2
    INPUT "can you hear?"; ans$
    IF ans$ = "no" THEN
        PRINT "your max frequency is:"; freq
        END
    END IF
    freq = freq + 2
LOOP

看看这个!


N = ABS(expression returning a numerical value)

返回表达式的“绝对值”,将负数变为正数(例如,-4 变为 4)。

PRINT ABS(54.345) 'This will print the value ABS now as it is (54.345)
PRINT ABS(-43)    'This will print the value as (43)

.

OPEN "file.txt" FOR APPEND ACCESS WRITE

这将设置已在程序中声明的文件的访问权限。程序员可以设置三个设置。它们是

READ - Sets up the file to be read only, no writing.
WRITE - Writes only to the file. Cannot be read.
READ WRITE - Sets the file to both of the settings above.

FOR APPEND 将文件打开为文本文件,并将文件指针设置为文件末尾,从而将新输出追加到文件。如果省略,FOR RANDOM 是默认值,它将文件打开为一系列固定长度的记录,并将文件指针设置为文件开头。新数据将覆盖文件中的现有数据,不会发出警告。

PRINT ASC("t")  'Will print 116

打印括号中找到的字符的 ASCII 代码编号。如果程序员在括号中输入字符串,则只会显示字符串的第一个字符。

ATN(expression)

内置三角函数的一部分。计算结果为数值的表达式将转换为其反正切。

angle = ATN( B ) 
angle2 = ATN( 23 / 34 )
BEEP

主板上的 BIOS 被指示从 PC '扬声器' 发出“哔”声。另请参见 SOUND 和 PLAY。

一个较旧、过时的替代方法是使用:PRINT CHR$(07)

此命令后来被 BEEP 命令替换。

BLOAD file_path$, memory_offset%

将使用 BSAVE 保存的文件加载到内存中。

  • file_path$ 是文件位置
  • memory_offset 是一个整数,指定要将文件加载到的内存偏移量

起始内存地址由偏移量和最近一次对 DEF SEG 语句的调用确定

BSAVE file_path$, memory_offset%, length&

将内存区域的内容保存到可以使用 BLOAD 加载的文件中

  • file_path$ 是文件位置
  • memory_offset 是一个整数,指定要保存的内存偏移量
  • length 要复制的字节数

起始内存地址由偏移量和最近一次对 DEF SEG 语句的调用确定

CALL ABSOLUTE

[编辑 | 编辑源代码]
CALL ABSOLUTE([argument%, ...,] address%)

将提供的参数(必须是 INTEGER)从左到右压入堆栈,然后对位于 address 的汇编语言例程进行远调用。要使用的代码段使用 DEF SEG 设置。通常 QBasic 会压入参数的地址,但如果参数之前有 BYVAL,则会压入参数的值。

请注意,由于 QBasic 从左到右压入参数,因此如果您提供三个参数,例如,堆栈将如下所示

SS:SP Return IP
+0002 Return CS
+0004 Argument 3
+0006 Argument 2
+0008 Argument 1

示例

'POP CX
'POP DX
'POP BX
'POP AX
'MOV [BX], AX
'PUSH DX
'PUSH CX
'RETF
A$ = "YZ[Xë•RQ╦" 'Codepage: 437
I% = 42: J% = 0
IF VARSEG(A$) <> VARSEG(J%) THEN STOP 'Both A$ and J% are stored in DGROUP.
DEF SEG = VARSEG(A$)
CALL ABSOLUTE(BYVAL I%, J%, PEEK(VARPTR(A$) + 3) * 256& OR PEEK(VARPTR(A$) + 2))
PRINT J%

QBasic 不会将 BP 设置为机器语言例程的堆栈帧,而是将其指向调用 QBasic 过程的堆栈帧,它看起来像这样

-???? Variable 3
-???? Variable 2
-???? Variable 1
-???? Return value (only if the procedure is a FUNCTION, absent if a SUB)
-0002 BP of calling procedure
SS:BP BP of calling procedure (yes, again)
+0002 Six bytes referring back to the calling procedure to use when executing END/EXIT SUB/FUNCTION
+0008 Argument 3
+000A Argument 2
+000C Argument 1

用 -/+???? 表示的偏移量将取决于变量的大小和存在、返回值和参数。例如,INTEGER 变量将占用两个字节,而 LONG 变量占用四个字节。正如人们可能预期的那样,考虑到 QBasic 如何传递参数,变量按声明的相反顺序存储。与调用机器语言例程时相反,这里的参数将始终是地址。对于按值传递的参数,将在堆栈上分配空间,并将该空间的地址传递给过程。

SELECT CASE expression
CASE test1[, test2, ...]: statements
[CASE test4[, test5, ...]: statements]
[CASE ELSE: statements]
END SELECT

执行第一个 CASE 语句之后的语句,其中测试匹配表达式。测试可以采用以下形式

expression
expression1 TO expression2
IS {<|<=|=|<>|>=|>} expression

这是一个没有 CASE 命令的程序的示例,它为值分配不同的路径

PRINT "1. Print 'path'"
PRINT "2. Print 'hello'"
PRINT "3. Quit"
INPUT "Enter a choice: "; a$
IF a$ = "1" THEN PRINT "path": RUN
IF a$ = "2" THEN PRINT "hello": RUN
IF a$ <> "3" THEN PRINT "That is not a valid choice.": RUN

这是使用 CASE 命令的程序的样子

PRINT "1. Print 'path'"
PRINT "2. Print 'hello'"
PRINT "3. Quit"
INPUT "Enter a choice: "; a$
SELECT CASE a$
CASE "1": PRINT "path": RUN
CASE "2": PRINT "hello": RUN
CASE IS <> "3": PRINT "That is not a valid choice.": RUN
END SELECT
CHAIN filename

这将执行链接到另一个 QBasic 程序。可以通过在 CHAIN 语句之前使用 COMMON 语句将值传递给另一个程序。请注意,除非第二个程序使用 CHAIN 将执行传递回第一个程序,否则执行不会返回到第一个程序。

CHDIR directoryname

这用于设置工作目录,也称为当前目录。目录名与 DOS 中的声明方式完全相同,不支持长文件名。例如

CHDIR "C:\DOS"

请注意,这不会更改当前驱动器,并且每个驱动器都有自己的工作目录。您可以像这样设置当前驱动器

SHELL "C:"

这将返回 ASCII 代码值的字符串字符符号。

name$ = CHR$([ascii character code])

通常用于在无法键入该字符时将字符“加载”到字符串变量中(例如 Esc 键或 F{n}(功能键)或 QBASIC 解释器会“识别”并执行的字符。以下四个字符不能出现在 QBasic 字符串文字中

  • 0 Null:到行尾的所有字符都将被删除,包括此字符。
  • 10 Line Feed:表示行尾。
  • 13 Carriage Return:此字符将被删除。
  • 34 引号:表示字符串文字的结尾。

这是一些字符代码的列表:-

07 Beep (same as BEEP)
08 Backspace
09 Tab
27 Esc
72 Up Arrow
75 Left Arrow
77 Right Arrow
80 Down Arrow

这将括号中的内容四舍五入到最接近的整数。

PRINT CINT(4573.73994596)

4574

CIRCLE ([X Coordinate], [Y Coordinate]), [Radius], [Colour],[Start],[End],[Aspect]

允许程序员显示一个圆圈。与所有图形命令一样,它必须与 SCREEN 命令一起使用。

CLEAR

重置所有变量、字符串、数组并关闭所有文件。QBasic 上的重置命令。

CLOSE

关闭所有打开的文件

CLOSE #2

仅关闭作为数据流 2 打开的文件。其他文件保持打开状态

CLS

清除活动屏幕。擦除所有文本、图形,将光标重置到左上角 (1,1),并将当前背景色(必须使用 COLOR 命令设置)应用于整个屏幕。

COLOR [Text Colour], [Background Colour]

这可以让您更改在下次“打印”到当前输出窗口时使用的文本和背景颜色。 它可以像这样完成

COLOR 14, 01
PRINT "Yellow on Blue"

您可以选择十六种颜色

00: Black            08: Dark Grey
01: Dark Blue        09: Light Blue
02: Dark Green       10: Light Green
03: Dark Cyan        11: Light Cyan
04: Dark Red         12: Light Red
05: Dark Purple      13: Magenta
06: Orange Brown     14: Yellow
07: Grey             15: White

这些值是您在 COLOR 命令中输入的数字。

注意 只有屏幕模式 0、7、8、9、10 支持背景颜色。 要用背景颜色“重新绘制”整个屏幕,请使用 CLS 命令。

将变量声明为“全局”,这允许在多个 QBasic 程序/脚本中访问其值(另请参阅 CHAIN 命令)

COMMON SHARED [variablename]

每个声明“variablename”为 COMMON 的程序将共享相同的值。

注意。 所有 COMMON 语句必须出现在程序的开头(即在任何可执行语句之前)。

修复变量,使其不能在程序中更改。

CONST (name) {AS (type = INTEGER / STRING)} = (expression or value)

例如:-

CONST PI = 3.14159265

将值 3.14159265 赋值给 PI。

CONST PI2 = 2 * PI

必须在使用 PI 计算 PI2 之前为 PI 赋值。 通常,所有 CONST 都在程序开头声明。

DATA [constant]

与 READ 和 RESTORE 命令结合使用。 主要用于处理图形的程序,此命令允许 QBasic 读取大量的常量。 READ 命令访问数据,而 RESTORE 命令“刷新”数据,使其可以再次使用。

一个系统变量,始终包含当前日期,以 mm-dd-yyyy 格式的字符串形式表示。 像这样使用它

a$ = DATE$

设置当前段地址。

DEG SEG [=address]
  • address 是一个段地址,可以包含 0 到 65535 之间的任何值。

如果省略 address,DEF SEG 会将当前段地址重置为默认数据段。 DEF SEG 由 BLOAD、BSAVE、CALL ABSOLUTE、PEEK 和 POKE 使用

DEST(仅限 QB64!)

[编辑 | 编辑源代码]

_DEST 设置当前写入页面或图像。 _DEST image_handle 将目标图像发送到存储在长变量 image_handle 中的句柄图像。 _DESt 0 将目标图像发送到正在使用的当前屏幕。


这用于声明数组(早期版本的 QBasic 要求定义所有变量,而不仅仅是大于 10 的数组)

DIM [Array Name] ([count],[count], ..)

数组名称可以是任何类型(整数、双精度、字符串等)。 如果未声明,则假定为单精度浮点数。 字符串可以使用 $ 符号(带有 % 符号的整数)“声明”。 QBASIC 解释器容忍不超过 10 个计数的数字数组,而不需要声明它们。

注意 早期版本的 QBasic 没有明确地将数组的内容设置为零(请参阅 CLEAR 命令)

DIM table%(100,2)

创建一个名为 table% 的整数数组,包含 100x2 = 200 个条目

DIM form$(5)

创建一个名为 form$ 的字符串数组,包含 5 个字符串

DIM quotient(20) AS DOUBLE

创建一个名为 quotient 的数组,包含 20 个双精度数字

DO .. LOOP

[编辑 | 编辑源代码]
DO
[program]
LOOP UNTIL [test condition becomes TRUE]

用于在程序中创建循环。 [condition] 仅在第一次执行 [program] 代码后测试(另请参阅 WHILE)。 例如

num$ = 1
sum$ = 0
DO
sum$ = 2 * num$
PRINT sum$
num$ = num$ + 1
LOOP UNTIL num$ = 13

这不起作用 但以下内容有效

num = 1
sum = 0
DO
sum = 2 * num
PRINT sum
num = num + 1
LOOP UNTIL num = 13
DRAW "[string expression]"

用于从当前“光标”位置以当前颜色绘制一条直线。 DRAW 定义方向(向上、向下等)和线的长度(以像素为单位)。 例如:-

SCREEN 7
PSET (50, 50), 4
DRAW "u50 r50 d50 l50"

每个数字前面的字母是方向

U = Up    E = Upper-right
D = Down  F = Lower-right
L = Left  G = Lower-left
R = Right H = Upper-left

绘制“光标”停留在线条结束的位置。 u50 从 50,50 向上绘制,结束于 50,0 r50 从 50,0 向右绘制,结束于 100,0 d50 从 100,0 向下绘制,结束于 100,50 l50 从 100,50 向左绘制,结束于 50,50

因此,显示的示例将绘制一个红色的“线框”正方形。

另请参阅 LINE 和 CIRCLE 命令。

注意:从 0,0 到 100,100 的对角线将长 100 * root(2) 像素(即 141)

END

表示程序的结束。 当 QBasic 看到此命令时,它通常会显示一条语句,提示:“按任意键继续”。

END TYPE / END DEF / END SUB / END FUNCTION / END IF / END SELECT

[编辑 | 编辑源代码]
ENVIRON [string expression]

注意:如果您在 Windows 系统上运行 QBasic,则无法使用此命令。

此命令可帮助您在会话期间设置环境变量。 从 QBasic.exe 解释器退出后,变量将恢复为其原始值。

这检查指定在 () 中的文件中是否还有更多数据值要读取。 EOF() 返回一个布尔值/二进制值,1 或 0。 如果未到达文件末尾,则为 0;如果读取了文件中的最后一个值,则为 1(另请参阅 LINE INPUT)

OPEN File.txt FOR INPUT AS #1
DO
INPUT #1, text$
PRINT text$
LOOP UNTIL EOF(1)
END

请注意,由于 INPUT 在到达 UNTIL 之前执行,因此 File.txt 必须包含至少一行文本 - 如果文件为空,您将收到“错误 (62) 输入超过文件末尾”。

ERASE [arrayname] [,]

用于删除所有已定义的数组。

系统变量,保存与处理上一行代码相关的数值。 如果该行完成且无错误,则 ERROR 设置为 0。 如果该行失败,则 ERROR 设置为下面所示的值之一。 最常用于将程序流重定向到错误处理代码,如:-

ON ERROR GOTO [line number / label]

如果 ERROR 非零,程序流跳转到指定的行号或标签。 如果 ERROR 为零,程序流继续执行下一行。

为了手动测试您的程序并检查错误处理例程是否正常运行,可以手动设置 ERROR:-

ERROR [number]

设置 ERROR = number

错误号如下所示

1 NEXT without FOR                 39 CASE ELSE expected 
2 Syntax Error                     40 Variable required 
3 RETURN without GOSUB             50 FIELD overflow 
4 Out of DATA                      51 Internal error 
5 Illegal function call            52 Bad file name or number 
6 Overflow                         53 File not found 
7 Out of memory                    54 Bad file mode 
8 Label not defined                55 File already open 
9 Subscript out of range           56 FIELD statement active 
10 Duplicate definition            57 Device I/O error 
11 Division by zero                58 File already exists 
12 Illegal in direct mode          59 Bad record length 
13 Type mismatch                   61 Disk full 
14 Out of string space             62 Input past end of file 
16 String formula too complex      63 Bad record number 
17 Cannot continue                 64 Bad file name 
18 Function not defined            67 Too many files 
19 Yes RESUME                       68 Device unavailable 
20 RESUME without error            69 Communication-buffer overflow 
24 Device timeout                  70 Permission denied 
25 Device Fault                    71 Disk not ready 
26 FOR without NEXT                72 Disk-media error 
27 Out of paper                    73 Advanced feature unavailable 
29 WHILE without WEND              74 Rename across disks 
30 WEND without WHILE              75 Path/File access error 
33 Duplicate label                 76 Path not found 
35 Subprogram not defined 
37 Argument-count mismatch 
38 Array not defined

请注意,ERROR 在执行失败时设置,而不是在“读取”代码时设置 - 因此,例如,在将结果分配给不存在的数组变量或写入不存在的文件之前,将发现“除以 0”。

允许立即退出子程序或循环,而不处理该子程序或循环代码的其余部分

EXIT DEF

从 DEF FN 函数退出。

EXIT DO

从 DO 循环退出,执行继续执行 LOOP 命令之后的命令

EXIT FOR

从 FOR 循环退出,执行将继续从 NEXT 命令之后的命令开始。

EXIT FUNCTION

退出 FUNCTION 过程,执行将继续从函数调用之后的命令开始。

EXIT SUB

退出 SUB 过程。

FOR .. NEXT

[edit | edit source]
FOR [variable name] = [start value] TO [end value] {STEP n}
[program  code]
NEXT [variable name]

变量被设置为 [开始值],然后执行程序代码,在 Next 语句中,变量被递增 1(或者,如果指定了,则递增 STEP 值)。结果值与 [结束值] 进行比较,**如果不相等**,程序流程将返回到 FOR 语句之后的行。

例如

FOR a = 200 TO 197 STEP-1
PRINT a
NEXT a

200 199 198

在使用 STEP 时要小心,因为很有可能用 STEP 跨过(结束值),结果 FOR 循环将“永远”运行(即,直到用户中止解释器或发生错误),例如:

FOR a = 200 TO 197 STEP-2
PRINT a
NEXT a

200 198 196 194 192 ... 0 -2 -4 ... -32768 ERROR 溢出

GOSUB

[edit | edit source]
GOSUB [subroutine line number / label]

命令处理跳转到指定的子程序。当遇到 RETURN 命令时,处理将返回到此点,并继续执行 GOSUB 下面的行。

IF [variable or string] [operator] [variable or string] THEN [command] {ELSE [command]}

比较变量或字符串。例如,如果您想检查用户输入的密码是否正确,您可能会输入
IF a$ = "password" THEN PRINT "Password Correct"
其中 a$ 是用户输入的密码。一些运算符包括
"="- 等于
"<"- 小于(仅在变量或字符串是数字值时使用)
">"- 大于(仅在变量或字符串是数字值时使用)
"<>"- 不等于
"<="- 小于或等于(仅在变量或字符串是数字值时使用)
">="- 大于或等于(仅在变量或字符串是数字值时使用)
还可以使用 if 命令对数字值执行操作,然后将它们与其他字符串或变量进行比较,例如以下示例:
IF a+5 = 15 THEN PRINT "Correct"
IF a*6 = b*8 THEN PRINT "Correct"

INCLUDE(仅限 QUICKbasic)

[edit | edit source]

QUICKBasic 支持通过 $INCLUDE 指令使用包含文件

(Note that the Qbasic interpreter does NOT support this command.)
'$INCLUDE: 'foobar.bi'

请注意,包含指令以撇号、美元符号为前缀,并且包含文件的名称用单引号括起来。

INKEY$

[edit | edit source]
[variable] = INKEY$

当您希望程序使用来自键盘的按键输入时,使用此方法。查看有关其工作原理的示例

a$ = INKEY$
PRINT "Press Esc to Exit"
END IF a$ = CHR$(27)

您可以将其与 CHR$ 命令结合使用,也可以输入字母(例如 A)。

INPUT

[edit | edit source]
INPUT [String Literal] [,or;] [Variable]

显示字符串文本,如果字符串文本后面跟着分号,则显示问号,并且用户输入直到他们按回车键为止,输入将输入到变量中。变量可以是字符串或数字。如果用户尝试为数字变量输入字符串,程序将再次要求输入。字符串文本是可选的。如果使用字符串文本,则需要逗号 (,) 或分号 (;)。

INPUT #

[edit | edit source]
INPUT #n [String Literal] [,or;] [Variable]

从指定的流文件 (参见 LINE INPUT #) 读取字符串/值

INPUT #1, a$, b$, n, m

从作为 #1 打开的文件中读取 4 个值。a$ 被分配了直到 ','(逗号)或行尾的所有文本,b$ 被分配了文本的下一段,然后解释两个数值并将它们分配给 n 和 m。

请注意,在文件中,数字可以用“任何东西”分隔 - 因此,如果在当前文件的“行”上没有找到数字(对于“n”或“m”),则将搜索文件的其余部分,直到找到数字为止。然后输入将“指向”文件中满足输入语句所需的最后一个数字后的位置(参见“seek #”命令)

INSTR

[edit | edit source]
INSTR (start%, Search$, Find$)

返回 Find$ 在 Search$ 中第一次出现的开始处的字符位置,从 Search$ 中的字符位置 'start%' 开始。如果未找到 Find$,则返回 0。start% 是可选的(默认值 = 1,Search$ 的第一个字符)

Pos = INSTR ("abcdefghi", "de")

返回 4

LEFT$()

[edit | edit source]
A$ = LEFT$(B$,N)

A$ 被设置为 B$ 的 N 个最左边的字符。

A$ =  LEFT$("Get the start only",6)

返回 "Get th"

另请参阅 RIGHT$()、MID$()。

LET [variable] = [value]

早期版本的 QBasic.exe 命令解释器需要使用 'LET' 命令将值分配给变量。后来的版本不需要。

LET N = 227 / 99
LET A$="a line of simple text"

等效于:

N = 227 / 99
A$="a line of simple text"
LINE ([X], [Y]) - ([X], [Y]), [Colour Number]

用于在 QBasic 中绘制线条。第一个 X 和 Y 用作线条开始处的坐标,第二个集合用于协调线条的结束位置。您必须在程序开头放置 SCREEN 命令才能使其正常工作。

注意。在 SCREEN 13 中,颜色编号 == 调色板编号

LINE INPUT #

[edit | edit source]
LINE INPUT #1, a$

从作为流 #1 打开的文件中以文本字符形式读取完整行,并将其放置在 a$ 中。

要找到“行尾”,QBasic 解释器会搜索“回车”+“换行”(0x0D、0x0A)字符。在读取在 UNIX/LINUX 系统上创建的文本文件(其中仅使用“换行”0x0A 来表示“行尾”)时,LINE INPUT 将无法识别“行尾”,并将继续输入,直到文件结束为止。对于超过 2k 个字符的文件,结果将是“字符串空间不足”错误,因为 a$ “溢出”。一个解决方案是使用能够处理 UNIX 文件的文本编辑器打开并“另存为”,然后尝试使用 QBasic 处理该文件。

LOADIMAGE(仅限 QB64)

[edit | edit source]

(注意!本节中的命令是指名为“QB64”的第三方程序。QUICKbasic 和 Qbasic 均不支持 _LOADIMAGE、_NEWIMAGE 或 _PUTIMAGE 命令。QUICKbasic 和 Qbasic 都有一个“SCREEN”命令,但它在这两种语言中的工作方式不同于在 QB64 中。)

_LOADIMAGE("image.jpg")

显示图像。必须与命令 SCREEN、_NEWIMAGE 和 _PUTIMAGE 一起使用。

示例

DIM rabbit AS LONG SCREEN _NEWIMAGE(800, 600, 32) rabbit = _LOADIMAGE("rabbit.jpg") _PUTIMAGE (100,100), rabbit

DO
[Program]
LOOP UNTIL [condition]

用于在程序中创建循环。此命令在循环开始后检查条件。它与 DO 命令一起使用。

LPRINT

[edit | edit source]
LPRINT [statement or variable]

将文本打印到打印机。LPRINT 命令期望打印机连接到 LPT1(PRN) 端口。如果打印机未连接到 LPT1,QBasic 将显示“设备故障”错误消息。

如果您的打印机连接到 COM 端口,请使用 MS-DOS MODE 命令将打印从 LPT1 重定向到 COMx(例如,要重定向到 COM1,请使用以下命令

   MODE LPT1=COM1

如果您需要在完成后取消重定向,请使用以下命令

   MODE LPT1
 a$=MID$(string$,start%[,length%])
 MID$(string$,start%[,length%])=b$

在第一个用法中,a$ 被设置为从字符串中获取的子字符串,从字符 start% 开始,取 Length% 个字符。如果省略 length%,则将取该行的其余部分(即 start% 和所有右侧的字符)。

在第二个用法中,string$ 的 length% 个字符被替换为 b$,从 start% 开始。如果省略 length%,则将替换该行的其余部分(即 start% 和所有右侧的字符)。

另请参阅 LEFT$ RIGHT$ LEN

 a MOD b

返回 a 除以 b 的整数商的余数

例如,10 MOD 3 返回 1

NEWIMAGE(仅 QB64!)

[编辑 | 编辑源代码]

_NEWIMAGE 用于将长变量设置为屏幕尺寸,或与 SCREEN 命令一起使用(见附录后面的内容)直接设置屏幕详细信息。它非常有用,因为您可以放大具有 RGB 颜色设置的 SCREEN 模式“13”,如果您发现默认尺寸太小。

语法:_NEWIMAGE(width,length,screen_mode)

  • width 和 length 是长变量,而 screen_mode 是您希望更改的屏幕模式格式。

例如:

    _NEWIMAGE(1000,1000,24),256

其中,256 是颜色的数量

它还用于为要放置的图像(首先使用 LOADIMAGE 加载它)准备窗口屏幕表面。

OPEN "[(path)\8.3 file name.ext]" (FOR {INPUT/OUTPUT} AS #{n})

这将打开一个文件。您必须提供 DOS 文件名,例如

OPEN "data.txt" FOR INPUT AS #1

以数据流 #1 的形式打开现有文件 data.txt 以供读取。由于未指定路径,因此该文件必须与 QBasic.exe 位于同一文件夹中 - 否则,处理将停止,并出现“文件未找到”错误

OPEN "C:\TEMP\RUN.LOG" FOR OUTPUT AS #2

以数据流 #2 的形式在 C:\TEMP 文件夹中打开一个名为 RUN.LOG 的空文件。任何同名的现有文件将被替换。

PALETTE[palette number, required colour]

仅适用于 VGA(SCREEN 模式 13),将调色板条目设置为新的 RGB 颜色。调色板编号必须在 1-256 范围内。所需颜色是由(所需蓝色 * 65536)+(所需绿色 * 256)+ 所需红色之和创建的 LONG 整数。

RANDOMIZE

[编辑 | 编辑源代码]
RANDOMIZE TIMER
A = INT((RND * 100)) + 1

RANDOMIZE 将为 QBasic 的随机数生成器设置种子。在 QBasic 中,通常只需使用 RANDOMIZE TIMER 来确保序列在每次运行时保持一致。

该示例是一个数学运算,用于从 1 到 100 获取一个随机数。

INT 代表整数,RND 代表随机,而“*”代表随机数要选择的范围。加“1”只是为了确保选择的数字是从 1 到 100 而不是从 0 到 99。

注意:此函数的后续调用不保证相同的随机数序列。

READ AIM(I)

此命令与 DATA 命令结合使用,允许 QBasic 读取数据。这主要用于处理大量数据,例如位图。

REM 或 '

[编辑 | 编辑源代码]
REM {comments}
' {comments}

当解释器在行首遇到 REM 或 " ' "(单引号)时,将忽略该行的其余部分

RETURN

表示子例程的结束

RANDOMIZE TIMER
A = INT((RND * 100)) + 1

RND 将提供 0 到 1 之间的随机数。

该示例是一个数学运算,用于从 1 到 100 获取一个随机数。RANDOMIZE TIMER 将为独特的序列设置初始种子。INT 代表整数,RND 代表随机,而“*”代表随机数要选择的范围。加“1”只是为了确保选择的数字是从 1 到 100 而不是从 0 到 99。

在内部,种子是一个 24 位数,以以下方法迭代:rnd_seed = (rnd_seed*16598013+12820163) MOD 2^24

PLAY "[string expression]"

用于在 PC 扬声器上播放 QBasic 中的音符和乐谱。音调由字母 A 到 G 表示。变音符用“+”或“#”(升调)或“-”(降调)表示,紧跟在音符字母之后。参见此示例

PLAY "C C# C C#"

字符串表达式中的空格将被忽略。还有一些代码用于设置持续时间、八度和速度。它们不区分大小写。PLAY 按字符串中出现的顺序执行命令或音符。任何更改属性的指示符对该指示符后面的音符有效。

Ln     Sets the duration (length) of the notes. The variable n does not indicate an actual duration
       amount but rather a note type; L1 - whole note, L2 - half note, L4 - quarter note, etc.
       (L8, L16, L32, L64, ...). By default, n = 4.
       For triplets and quintets, use L3, L6, L12, ... and L5, L10, L20, ... series respectively.
       The shorthand notation of length is also provided for a note. For example, "L4 CDE L8 FG L4 AB"
       can be shortened to "L4 CDE F8G8 AB". F and G play as eighth notes while others play as quarter notes.
On     Sets the current octave. Valid values for n are 0 through 6. An octave begins with C and ends with B.
       Remember that C- is equivalent to B. 
< >    Changes the current octave respectively down or up one level.
Nn     Plays a specified note in the seven-octave range. Valid values are from 0 to 84. (0 is a pause.)
       Cannot use with sharp and flat. Cannot use with the shorthand notation neither.
MN     Stand for Music Normal. Note duration is 7/8ths of the length indicated by Ln. It is the default mode.
ML     Stand for Music Legato. Note duration is full length of that indicated by Ln.
MS     Stand for Music Staccato. Note duration is 3/4ths of the length indicated by Ln.
Pn     Causes a silence (pause) for the length of note indicated (same as Ln). 
Tn     Sets the number of "L4"s per minute (tempo). Valid values are from 32 to 255. The default value is T120. 
.      When placed after a note, it causes the duration of the note to be 3/2 of the set duration.
       This is how to get "dotted" notes. "L4 C#." would play C sharp as a dotted quarter note.
       It can be used for a pause as well.
MB MF  Stand for Music Background and Music Foreground. MB places a maximum of 32 notes in the music buffer
       and plays them while executing other statements. Works very well for games.
       MF switches the PLAY mode back to normal. Default is MF.
PRINT [Argument] [,or;] [Argument]...

将文本显示到屏幕上。参数可以是字符串字面量、字符串变量、数字字面量或数字变量。所有参数都是可选的。

PRINT #[n] [,or;] [Argument]...

将数据保存到“OPEN FOR OUTPUT AS #[n]”打开的文件中,或者我们可以使用“?”符号来表示打印命令

PSET ([X coordinate],[Y coordinate]), [Pixel Colour]

此命令显示像素,可以一次显示一个像素,也可以一次显示一组像素。要使该命令正常工作,程序中必须包含 SCREEN 命令。

SCREEN [Screen Mode Number]

此命令用于在屏幕上显示图形。QBasic 中有十种主要的屏幕模式类型,具体取决于您想要的屏幕分辨率。以下是您可以选择的屏幕模式列表

SCREEN 0:文本模式,不能用于图形。这是基于文本的程序运行的屏幕模式。

SCREEN 1:320 x 200 分辨率。四种颜色

SCREEN 2:640 x 200 分辨率。两种颜色(黑色和白色)

SCREEN 7:320 x 200 分辨率。十六种颜色

SCREEN 8:640 x 200 分辨率。十六种颜色

SCREEN 9:640 x 350 分辨率。十六种颜色

SCREEN 10:640 x 350 分辨率。两种颜色(黑色和白色)

SCREEN 11:640 x 480 分辨率。两种颜色

SCREEN 12:640 x 480 分辨率。十六种颜色

SCREEN 13:320 x 200 分辨率。256 种颜色。(推荐)

注意:在 SCREEN 13 中,您拥有 256 种颜色的调色板。该调色板由 Windows 预设,但是您可以使用 PALETTE 命令更改 RGB 值。

SEEK #[file number], 1

将“input #”指针重新定位到文件开头。

SGN(expression yielding a numeric value)

产生值的“符号”,如果 < 0 则为 -1,如果为 0 则为 0,如果 > 0 则为 1

“SHELL”命令用于在 Qbasic 中向命令提示符/Windows Shell 发出命令。 “Shell”命令与包含命令的字符串一起使用,这些命令会被上述任何软件识别。字符串中包含的命令类似于 MS-DOS 的命令

示例:SHELL 可与“DIR”命令一起使用,以创建特定文件夹或路径中文件的目录。


SLEEP [n]

执行暂停 n 秒

SOUND [frequency], [duration]

与 BEEP 命令不同,它从 PC 扬声器发出可变频率和持续时间的音频。频率以赫兹测量,范围为 37 到 32767。在频率部分输入这些数字之一。持续时间是时钟滴答声,默认值为每秒 18.2 个滴答声。

将数值转换为文本(字符串)字符

A$ = STR$(expression yielding a numeric value)

数值将被转换为文本字符,并放置到 A$ 中。用于将数字转换为文本字符串。

警告。

1) 如果结果为正数,将在前面添加一个“空格”(STR$(123) = " 123" 而不是 "123",这可能与预期不符)。如果结果为负数,则不会使用空格,而是使用“-”(减号),即 STR$(-123) = "-123" 而不是 " -123",这可能与正数的行为预期不符。

2) 当将小于 0.1 的浮点数(mumb!、numb#)转换为字符串值时,该字符串值可能会以“科学计数法”呈现,使用“D”而不是“*10^”(例如 "5.nnnnnnD-02" 而不是 " .05nnnnnn" 或 "5.nnnnnn*10^-02")。这仅在需要保留有效数字时才会发生(因此 .03000000 被呈现为 " .03",而 .030000001 被呈现为 " 3.0000001D-02"),这可能与您的预期不符。

另请参阅 CHR$,用于将 ASCII 值转换为字符串字符。

另请参阅 LEFT$、MID$、RIGHT$,用于从一行文本中提取子字符串。

SYSTEM

.bas 退出,QBasic.exe 解释器关闭,并将“控制权”传递给命令窗口 c:\ 提示符(或调用 .cmd 脚本的下一行等)。

注意!:这仅在您使用“/run”参数在命令提示符下启动程序时才有效!(例如:“Qbasic /run MyProg.bas”)否则,Qbasic 会假设您打开程序是为了进行更改,因此“SYSTEM”会将您带回到编辑器屏幕。

[Command] [variable] = [value] THEN GOTO [line command value]

与 GOTO 或 IF 条件命令结合使用。它告诉计算机在满足特定条件时该怎么做。

[Command] [Variable] = [Value] TO [Value]

通常用于输入多个变量。

FOR a = 400 TO 500
PRINT a
NEXT a

此示例将打印从 400 到 500 的所有数字。无需分别声明所有值,我们可以在一次声明中声明它们。

USING "format";

用于格式化 PRINT 命令输出的数据。通常,QBasic 解释器将以 8 个字符打印一个数字,前面有尽可能多的空格。要更改此行为,可以使用 USING 命令来格式化输出。例如..

IF n > 99 THEN PRINT #1, USING "###"; n; ELSE IF n > 9 AND n<=99

THEN PRINT #1, USING "0##"; n; ELSE PRINT #1, USING "00#"; n;

.. 将输出从 0 到 999 的 n,并在前面添加零。请注意 n 后面的“;”。这意味着“不要换行”,这会导致下一个 PRINT #1 在逗号(“,”)之后直接添加数据(Qbasic 会自动插入逗号而不是换行符)。

name=VAL([variable$])

将 [变量字符串] 的内容转换为数值,以便在计算中使用。如果 (name) 是 INTEGER 类型,则 VAL 会向下取整。另请参阅 STR$。

A$ = "2"

B$ = "3"

X = VAL(A$) + VAL(B$)

PRINT A$; " + "; B$; " ="; X

WHILE ... WEND

[编辑 | 编辑源代码]
WHILE {NOT} [test condition is true]
[program code to execute]
WEND

测试条件,如果为真(或不为真),则执行 [程序] 代码,直到遇到 WEND,此时控制权将传递回 WHILE 行。

WHILE NOT (EOF(1))
LINE INPUT #1, A$
PRINT #2, A$
WEND

在文件 #1 的结尾未到达之前,读取每行完整的行并将它们写入文件 #2。

与 FOR 和 DO 不同,无法从 WHILE 循环中退出。

ASCII 表

[编辑 | 编辑源代码]
ASCII Character Codes 0-127
ASCII 字符代码 0-127
ASCII Character Codes 128-255
ASCII 字符代码 128-255

此作品的作者是

Faraaz Damji (Frazzydee)
Adam Colton
Gareth Richardson (Grich)
Debanshu Das

华夏公益教科书