一、程序设计语言的选择 程序是用来实现算法的。 1、应用范围
.数值计算(科学计算)
FORTRAN 、True BASIC、QBasic .商业和管理
COBOL、数据库系统(dBASE、FoxBASE、Foxpro) .人工智能
Lisp、ProLog .系统设计
C语言、C++、
.多媒体(图、声、文技术) Visual BASIC .计算机网络
分布处理数据库系统:SYBASE、ORACLE
WWW文件:HTML(Hyper Text Markup Language)、Java 2、语言所提供的功能强弱 3、语言提供的数据结构 数据类型
4、语言的使用环境
DOS、WINDOWS、UNIX、NOVELL 5、程序设计环境
集成环境(菜单功能)、图形界面、软件开发工具 6、使用者的背景
熟练程度、使用环境
二、BASIC语言的发展
.BASIC语言于1964年问世 作者:John.G.Kemeny 和 Thomos E.Kurtz
.Beginner's All-purpose Symbolic instruction Code\" 1、初期的BASIC(第一代)
.14——17个语句,Minimal BASIC .自己操作(输入、运行、修改、输出 2、微机BASIC(第二代)
.Microsoft总裁Bill.Gates编写只有4k字节的解释程序 .TRS-80 BASIC .Apple BASIC
.MSBASIC(BASICA) .GWBASIC
3、结构化BASIC(第三代)
.限制GOTO语句,程序模块化 .True BASIC 真正的BASIC .Quick BASIC .Turbo BASIC
.QBasic(DOS5.0以上) 4、面向对象的BASIC
.windows环境下的Visual BASIC,图形界面,支持多媒体.
三、QBasic的特点
QBasic是结构化的程序设计语言,与第二代BASIC相比有如下特点: 1、扩充了变量和常量的类型 .变量名长度:40个字符
.增加了长整型、定长字符型变量 .可定义数值常量、字符串常量 2、提供了新的选择结构 .条件语句
IF <条件> THEN <语句组1> ELSE
<语句组2> END IF
.多分支语句SELECT 3、改进了循环结构
增加以下两个循环语句: .WHILE循环
WHILE <条件> <循环体> WEND .DO循环
DO WHILE <条件> <循环体> LOOP
4、子程序和函数作为单独的模块 5、不需要行号
6、具有良好的编辑环境 7、提供联机“Help”
8、提供“分步执行”“跟踪”等调试 9、采用先进的解释执行方式 10、与Visual BASIC完全兼容
四、QBasic使用环境 1、启动
.在DOS状态下运行QBASIC,如: F:\\>QBASIC .在WIN98下双击QBASIC图标; .软盘启动
把QBASIC系统文件(QBASIC.EXE、QBASIC.HLP) 复制到A盘,再执行:A:\\>QBASIC 2、工作窗口
.程序窗口(上)
.命令窗口(下)
.两窗口之间的切换F6
3、基本操作
光标、行列位置、鼠标指针、菜单、窗口的缩放
五、运行程序
1、从键盘输入程序 2、运行程序
.选择菜单RUN中的“Start\"命令 .直接按F5键或Shift+F5 .在命令窗口中输入run命令 3、修改和编辑源程序
删除、插入、复制、粘贴 4、程序存盘和从磁盘读入程序 5、退出QBasic
第二章 QBasic程序设计初步 一、概述
程序设计要掌握如下几点: 1、语法规则
计算机是忠实的执行者
2、根据算法写出程序
掌握算法,会画流程图 3、数据结构
数据的组织形式 4、结构化程序设计方法
掌握三种基本结构的运用 5、程序运行的环境
了解计算机系统的硬件和软件配置
程序设计=算法+数据结构+程序设计方法+语言工具和计算机环境
二、源程序结构
1、一个程序由若干个语句行组成,每一行称为一个语句行,一行中可以包含多个语句(语句间用“:”号相隔)。
2、语句行可以没有行号,程序按语句排列的顺序依次执行,但也允许有行号,行号仅作为行标号(源程序转移的目标)而不代表执行顺序。 3、语句结构
<语句定义符> [<语句体>] (关键字)
4、程序以END语句结束
可以有多个END语句,一般放在程序的最后。 5、行标号 .行的标志
.只能在一行的开头
.可独占一行(即为空语句) 6、主程序与子程序
一个程序只包含一个主程序,但可包含若干个子程序或函数。 三、常量
常数——不变的数 常量——不能改变的数据 1、数值常量(常数) 1)整型常量(整数)
由若干个数字组成的序列 2)实型常量(实数)
.定点数(日常记数法) 小数位固定
.浮点数(科学记数法) 用E代表以10为底的幂数,即把常量用指数形式来表示 例如:12.34E2表示1234
.单精度实数(普通型实数)——7位有效数字 .双精度实数——16位有效数字(用D代替E) 3)数的范围
类型 标记符 字节 有效位数
整数 % 2 长整数 & 4
单精度定点数 单精度浮点数 双精度定点数 双精度浮点数 ! 4 E 4 # 8 D 8 7 7 15 15
2、字符串常量
用双引号把若干个合法字符括起来,如: \"QBasic\" \"abc123\"
3、符号常量
CONST <符号>=<常量>
例如:CONST pi=3.14159
四、变量
可改变的量,如: let a=1 let a=2.3 let a=45.9 print a end
1、变量名和变量的值 1)变量名规则
.变量名的第一个字符必须是字母
.变量名中第2个字符及其后的字符可以是字母、数 .变量名的长度范围为1-40个字符
.表示变量类型的符号应作为最后一个字符 .QBasic的保留字不能用作变量名. .变量名中的大小写字母等效 .变量名中不可有空格 2)变量的名与值
变量名——符号地址 变量值——存储内容
系统自动生成变量名与内存地址对照表 2、变量类型
1)变量名后加类型定义符 %——整型(INTEGER) &——长整型(LONG)
!——单精度实数(SINGLE) #——双精度实数(DOUBLE) $——字符串(STRING) 2)DIM语句
DIM <变量名> as <类型>
字或小数点 .<变量名>不加类型符
.用DIM定义了的变量其末尾加或不加类型定义 符都是合法的且都表示同一变量
3)字符串变量
.可变长字符串变量 a$=\"abcde\" a$=\"1234567\" .固定长度的字符串变量 例如: DIM a as string*5 a=\"China\"
a$=\"Shanghai\" PRINT a,a$ END 运行结果如下:
Shang Shang
课本P78表4.3列出了变量的类型定义方法及占用的内存量
五、标准函数
.课本P80表4.4列出了最常用的一些数学函数 .课本P361第13.4节列出了QBasic的所有函数
标准函数——类似数学函数y=f(x)
例如:计算x+y的平方根 SQR(x+y) 计算sin(a+b) SIN(a+b)
六、运算符和表达式
QBasic的三种运算:算术运算、关系运算、逻辑运算 1、算术运算符
加 + 4+5 =9 减 - 8-3 =5 乘 * 2*3 =6 除 / 5/2 =2.5 整除 \\ 5\\2 =2 求余 MOD 5 MOD 2 =1 乘方 ^ 2^3 =8
注:对于整除和求余运算,若参与运算的数不是整数,则先按四舍五入的原则变成整数后再运算。
2、算术表达式
.QBasic表达式
用运算符和括号将若干运算量(包括常量、变量、函数等)连接起来的式子。(例4.1)
.算术运算符的优先顺序:
括号—正负号—函数—乘方—乘、除、整除—余数—加、减 .表达式的写法
表达式应写出在同一行,注意分式的写法。 第三章 顺序程序设计 程序的执行次序,从上到下,由一些非控制转移语句组成 一、输出语句
输出用户所需的信息 1、一般格式
PRINT [<表达式>] 表达式—常量、变量、函数 如: PRINT 2,4,6 PRINT \"X=\";X 显示:
X= ... 2、作用
(1)输出数值计算的结果(P92) (2)输出字符串(P93) (3)输出系统信息(P94) 3、输出格式
(1)标准格式—输出项以逗号分隔 五区—每区14列
(2)紧凑格式—输出项以分号相隔 (3)TAB(X)—第X列
定位输出,但在同一行中、TAB(X)中的X应从左到右逐渐增大。还可利用SPACE(X)插入空格
(4)PRINT <....>, 不换行(光标到下一区)
PRINT <....>; 不换行(光标在输出项后) PRINT <....> 换行 PRINT 空行 4、打印输出
LPRINT
其使用方法与PRINT相同 二、赋值语句
1、一般格式
[LET]<变量名>=<表达式> LET a=100
LET a$=\"BOOK\" 2、作用
计算右边的表达式,将其值赋给左边变量; 主要作用:运算。
“=”的作用于是赋值,与等于的差别 如:X=Y 与 Y=X 不同(例P100) 3、对变量的赋值操作 (1)变量的初值为0 未赋值的变量
(2)一个变量只有一个值
变量的当前值由最后一次赋值决定 n=n+1 (3)变量值的传递
a=b b的值不变 b=a a的值不变 (4)关于赋值类型
以左边变量的类型为准 (5)两个变量交换值 a=b c=a
a=b c为中间结果为?/font> b=c
三、键盘输入语句 1、一般格式:
INPUT[“提示信息”;]< 变量表>
说明:(1)执行该语句从键盘输入数据的数目应与语句 (2)从键盘输入的数据只能是常量 (3)输入时数据间用逗号分隔 例:求学生三门课的平均成绩 INPUT \"a,b,c=\";a,b,c V=(a+b+c)/3 PRINT \"average=\"; v END
四、读入语句
1、格式: READ <变量表> DATA <数据表>
例:READ a,b,c, DATA 75,60,90 V=(a+b+c)/3 END
中的变量个数相同 2、说明:
(1)<数据表>中的数据个数不能少于<变量表>中的变量个数。
(2)DATA语句可放在程序的任何位置,可使用多个DATA语句来存放数据,这时将按DATA语句的先后顺序,把数据放数据区。
(3)关于“数据指针”当指针移到数据区之外时,屏幕给出错误信息:
Out of DATA (例P109)
(4)DATA语句中的数据只能是常量 五、恢复数据指针语句 RESTORE
将数据指针移至首位或指定的DATA语句标号。
六、结束语句和暂停语句 1、END语句
结束程序运行。一个程序可有多个END语句,但运行程序时,只有一个起作用,即执行其中一个END语句都会使程序结束。 2、STOP语句
使程序暂停,选择RUN-CONTINUE继续运行。
七、程序调试 1、分步执行
F9—单步执行,STEP
F6—窗口转换,WINDOWS F5—运行或继续运行。 2、设置断点
F9—设置断点 F5—运行或继续运行
第四章 选择结构程序设计 一、概述
分支结构: 二、关系式和逻辑表达式 1、关系运算符
< 、 >、 =、 <=、 >=、 < > 2、关系式
关系式是由一个关系运算符把两个表达式连起来的式子。结果(值)为逻辑值: 真 True 假 False QBASIC用数值表示: 真: -1(非零值) 假: 0
if x< >0 then print x和if x then print x 相同 3、逻辑运算符及逻辑表达式
(1)、not (非、逆、取反) 7>4 值为真
not (7>4) 值为假 (2)、and (与、交)
所连接的两个关系式为真时条件成立。 x>0 and x<10 (3)、or (或 、并)
所连接的两个关系式中有一个(以上)为真,则条件成立。 X> 10 or X<0 集合表示
A and B A or B not A 4、逻辑表达式的运算规则 5、运算次序(优先级别)
算术运算—关系运算—逻辑运算(例P123) 关于逻辑表达式结果: x=6>4
print x x=-1 a=5=3 =>a=(5=3) a=0
三、行IF语句 1、一般格式
if <条件> then <语句1> [else<语句2>]
2、嵌套关系
(1)if…then if…then…else…else 内层 外层
(2)if…then if…then…else if …then…else
四、块if语句
1、一般格式
if <条件> then <语句组1> [else
<语句组2>] end if 2、应用举例
例6.5: 输入3个整数、按从大到小的顺序输出。 算法:
(1)先将a与b比较,把小者放b中,大者放a。
(2)再将a与c比较,把小者放c中,大者放a中,此时 a 已是三者最大的。
(3)最后将b与c比较,大者放b中,小者放c中,此时 a、b、c已按从大到小的顺序排例好。 程序:
inpnt \"a,b,c,=\";a,b,c if b>a then t=a
a=b 交换a、b(swap a,b) b=t end if
if c>a then t=a
a=c 交换a、c(swap a,c) c=t end if
if c>b then t=b
b=c 交换b、c (swap b,c) c=t
end if
print a, b,c end 3、块if的嵌套 if then …
if then … else … end if … else … end if
4、块IF中的ELSEIF格式 if then … else
if then … else …
end if end if 写成: if then …
elseif then … else … end if P125 改写为:
Input \"m=\";m If m<100 then d=0
elseif m<200 then d=0.01
elseif m<300 then d=0.02
elseif m<500 then d=0.03
elseif m<1000 then d=0.04
elseif m<2000 then d=0.05 else
d=0.08 end if
a=m*(1-d)
print \"amount=\";a end
五、多分支选择语句
用嵌套的IF语句可实现多分支选择 1、基本格式
select case <变量> case <值1> <语句组1> case <值2> <语句组2> …
case <值n> <语句组n> case else
<语句组n+1> end select
每一个CASE句中指定一个值条件,当CASE变量的值符合条件时,执行该子句下面的语名组,在执行完该语句组后,跳过其它CASE子句,从END SELECT转出。 c=int(s/250)
2、在CASE子句中使用TO
CASE <值1> TO <值2> 3、在CASE子句中使用IS
CASE IS <关系运算符> <表达式> 4、在CASE子句中使用多个条件
允许在一个CASE子句中指定多个条件,各条件 之间用逗号分开。 条件=单值、值范围、单条件 5、SELECT CASE语句的一般格式 select case <测试表达式>
case <条件11>,<条件12>,… <语句组1>
case <条件21>,<条件22>,… <语句组2> …
case <条件n1>,<条件n2>,… <语句组n> case else
<语句组n+1> end select
六、多分支转移语句
格式:ON <算术表达式> GOTO <标号1>,<标号2>,…
七、多分支选择结构小结
1、IF-THEN-ELSE(用IF的嵌套) 分支(条件)较少时使用。 2、SELECT CASE
分支(条件)较多时使用。 3、ON GOTO
非结构化程序设计,不宜使用。 第五章 循环结构程序设计 一、概述
循环结构:
(1)、WHILE循环 (2)、FOR循环 (3)、DO循环
循环体——反复执行的一组语句 例:求s=1+2+3+...+100 编写如下程序:
s=0
for i=1 to 100
s=s+i 反复执行100次 next i
print \"1+2+3+...+100=\";s
end
二、WHILE循环结构
WHILE <条件>
<循环体> WEND
注: <条件>是终止循环的逻辑表达式,<条件>应随循环的执行而变化,最终退出循环。 如: s=0 i=1
WHILE i<=100 s=s+i WEND
构成“死循环”——无终止的循环。这时可用Ctrl+Break终止其程序运行。
例1: 如果我国工农业生产每年以12%速度增长,问多少年后产值翻一番:基值设为100。 (逐年计算产值,看是否达到200) p=100 r=.12 n=0
WHILE p<200 p=p*(1+r) n=n+1 WEND
PRINT n; \"years\ END
例2 : 给出两个正整数,求它们的最大公约数。 算法:(辗转相除法)
(1)、以大数m作被除数,小的数n作为除数,相除后余数为r。
(2)、如果r=0,则n就是最大公约数。否则将n=>m, r=>n, 重复(1)。 程序及框图 :
INPUT \"m,n=\";m,n r=m MOD n
WHILE r < >0 m=n n=r
r= m MOD n WEND
PRINT \"最大公约数为:\ END
例3:给一个整数n(>2),判别它是否素数(质数)。 算法:判别n是否素数,只要将n被1~(n-1)各数轮流作除数除,若都不被整除,则为素数。 若n不是素数,则n=n1*n2,而n1和n2中必然有一个大于或等于n的开方根,另一个小于或等于n的开方根。
即若n是非素数,则必然有一个因子小于或等于n开方根。 程序及框图:
INPUT \"n=\"; n k=INT(SQR(n)) i=2 flag=0
WHILE i<=k AND flag=0
if n MOD i=0 THEN flag=1 ELSE i=i+1 WEND
IF flag=0 THEN PRINT n;\"是素数!\" ELSE
PRINT n;\"不是素数!\" END IF END
二、FOX循环结构 1、格式
FOR <变量>=<初值> TO <终值> STEP <增量> 循环体
NEXT <变量>
如: for i=1 to 10 step 2 print i, next i 2、说明
(1)FOR与NEXT必须配对; (2)FOR必须在NEXT的前面;
(3)FOR中的循环变量与NEXT的变量一致; (4)步长为1时“ STEP 1”可省略;
(5)循环终止的条件是循环变量赋值超过终值,而不是等于终值。 (6)循环次数的计算 次数=(终值一初值)/步长+1
(7)循环变量尽量用整型变量;
(8)循环变量初值和终值、步长值均可以是正值、负值或零,也可是整数或小数; 终止条件:当步长>0时,循环变量>终值 当步长<0时,循环变量<终值 当步长=0时,永不终止
(9)循环变量主要用来控制循环、可在循环体内引用,也可不在循环体出现。
for i=1 to 100
print \"a\" next i
for i=1 to 100
print i, next i
注意:在循环体内可对循环变量赋值,但这将改变循环次数。
for i=1 to 100
print i, i=i+1 next i
3、exit for 语句 提前终止循环 for i=1 to 100 s = s + i * i
if s > = 100 then exit for next i print s end
4、应用举例
判别n是否素数。
input \"n=\";n
k = int(SQR(n)) f = 0
for i% = 2 to k
if n mod i% = 0 then f = 1 exit for endif next i%
if f = 0 then
print n ; \"是素数\" else
print n ; \"不是素数\" endif
end
斐波那契数列
f(n)=1 (n<=2) f(n)=f(n-1)+f(n-2) (n>2)
f1=1 f2=1
f3=f2+f1=2 f4=f3+f2=3 f5=f4+f3=5 ...... 程序如下: f1=1 f2=1
print f1,f2,
for i% = 3 to 20
f3 = f1+f2 print f3, f1=f2 f2=f3 next i% print end
猴子吃桃:每次吃掉一半多一个,直到第10天只剩一个,第一天共摘了多少个桃子?
x10 =1 程序如下: x =1
for n%=10 to 2 step -1 x=(x+1)*2 next n%
print \" 桃子的数量为:\";x end
思考:for n%=10 to 1 step -1 或for n%=1 to 9
三、DO 循环语句
1、简单DO循环 DO
<循环体> loop
终止循环可用: exit do 计算三门课程的平均成绩
do
input\"a,b,c, =\";a,b,c
if a=0 and b=0 and c=o then exit do s=(a+b+c)/3
print \"平均成绩:';s loop end
2、带while子句的DO循环语句
格式一:do while <条件> <循环体> loop 格式二:do
<循环体>
loop while <条件>
作用:当指定条件为真是继续循环,否则结束循环。`
格式一为前测试与while...wend相同。格式二为后测试,至少应执行循环体一次。 例:求1+1/2+1/3+.......1/n 直到前后两项之差小于是1e-3为止。s=0
n=1 t=1/n do
t1=t s=s+t1 n=n+1 t=1/n
loop while t1-t>=1e(-3) print s end
思考:(1)用do while...loop 改写程序; (2)两种格式do 循环的区别? 3、带until子句的do循环语句
格式一:do until <条件>
<循环体>
loop 格式二:do
<循环体>.
loop until <条件> 作用:当条件为真时终止循环
求2000~2050年之间的所有闰年。 闰年的条件是:
(1)能被4整除,但不能被100整除的年份都是闰年; (2)能被100整除,又能被400整除的年份是闰年; 程序如下: y=2000
do while y>2050
if y mod 4=0 and y mod 100<>0 then
l=1
elseif y mod 100=0 and y mod 400=0 then l=1 else
l=0 endif
if l=1 then print y, y=y+1 loop end
思考: 条件可写成:
(1)if (y mod 4=0 and y mod 100<>0) or (y mod 100=0 and y mod 400=0) else l=0
(2) if y mod 4=0 then
if (y mod 100)<>0 then
l=1
elseif (y mod 400)=0 then
l=1
else
l=0 endif
人口增长平均1.5%,设现人口12.3 亿,问多少年后人口达到或超过15亿。p=1.23e+0.9 r=0.015 n=0 do until p>=1.5e+0.9
p=p*(1+r) n=n+1 loop print n;\"年\人口\";p end
问题(1)比较下面两例:
then l=1
f=1 f=1
n=6 n=6 do until n>5 do
f=f*n f=f*n n=n+1 n=n+1 loop loop until n>5 print f print f end end
(2)凡是用do until循环可以解决的问题,全部可用do while解决,只需把“<条件>”取成“<反条件>”
p=1.23e+0.9 r=0.015 n=0 do while p<1.5e+0.9
p=p*(1+r) n=n+1 loop print n;\"年\人口\";p end
四、循环的嵌套
一个循环体内包含另一个循环
找出100-200间的全部素数。
for n=101 to 200 step 2
k=int(SQR(n)) i=2 f=0 while i<=k and f = 0
if n mod i=0 then f=1 else i=i+1 wend if f=0 then print n, next n end
例打印乘法九九表
for i=1 to 9
for j=1 to 9
p = i*j print p, next j print next i
end 打印表格(P175) print TAB(5);\"|\" for j=1to 9
print tab(j*8);j; next j print
for n=1 to 75
print \"-\";
next n print tab(5);\"|\"; print
for i=1 to 9
print i;\"|\"; for j=1 to 9
p=i*j
print TAB(j*8); p; next j print next i
for n=1 to 75
print \"-\"; next n end
注:1)内外循环不应交叉
2)内外循环的变量名不应相同
第六章 函数与子程序
“模块化程序设计”中的“模块”是指:完成程序全部或部分任务的独立源程序文件。 程序的每一个模块可以是子程序或函数,它是通过执行一系列语句来完成一个特定的操作过程,常称为“过程”。
“执行一个过程”——调用一个子程序或函数; 一、自定义函数 QBASIC函数: ①标准函数 ②自定义函数 ③外部函数
1、单行自定义(DEF)函数
语句函数——用一个语句定义一个函数 (1). 一般格式;
DEF fn<名字>(<参数>)=<表达式>
例1. 已知圆的半径r,求圆的面积:S=πr2
DEF fns(r)=3.14159*r*r PRINT fns(3) END
例2.DEF fns$=”this is a string”
PRINT fns$
例3. 求以下公式:
DEF fnc(a,b)=SQR(a*a+b*b) Print fnc(3,4)
(2).说明
• 函数名由两部分组成 fn s
自定义函数标志(fn),用户定义名(一个字母s);
• 参数可有多个,但调用时的参数(实参)与定义时的参数(形参)要一致。 2、多行自定义(DEF)函数 用多行语句来定义一个函数。 (1)、一般格式
DEF fn<名字>(<参数>) ......
fn<名字>=<表达式> END DEF
例4、定义函数f(n)=1+2+...+n
DEF fns(n)
S=0
FOR i=1 to n
S=S+i Next i fns=S END DEF
For n=1 to 100
Print fns(n) NEXT n END
(2)、说明
(i)形式参数——定义函数的自变量 实际参数——调用函数时的参数。 (ii)函数先定义后使用,即习惯把DEF语句放在程序的开头。
二、块内子程序
1、gosub-return 语句
子程序定义:
<标号或行号>: ...... return 子程序调用:
GOSUB <标号或行号>
例5:求4!+5!+6!
S=0
n=4: gosub f:s=s+p n=5: gosub f:s=s+p n=6: gosub f:s=s+p print “4!+5!+6!=”;s end f: p=1
for i=1 to n
p=p*i next i return
2、on gosub-return 语句 (1).一般格式 子程序定义:
<标号>: ...... return
子程序调用:
ON <表达式> gosub <子程1>,<子程2>,…,<子程n>
例:“小学生算术练习”——轮流出一个二位数和一个一位数的加法、减法和乘法的题目,共出十题,每题 10分。
RANDOMIZE for i=1 to 10
a=int(90*RND)+10 b=int(9*RND)+1 p=i mod 3 + 1
ON p GOSOB a1,a2,a3 Next i
Print \"n=\";n*10 END
a1: print a;\"+\";b;\"=\"; input c
if c=a+b then n=n+1 return
a2: print a;\"-\";b;\"=\"; input c
If c=a-b then n=n+1 Return
a3: print a;\"*\";b;\"=\" Input c
If c=a*b then n=n+1 Return.
(2)、说明:
<表达式>的值不是整数时,按四舍五入处理,值为0或大于n则不起作用,值为负时系统给出错误信息——“不正确的函数调用”。 3、ON KEY(n) GOSUB-RETURN 语句 (1)、调用格式
ON KEY(n) GOSUB <标号>
其中n是数值表达式,代表一个“陷阱键”。n的值与设定键的对应关系如下:
n值 1~10 11 12 13 14
例: 求和式:S=12+22+...+n2 n=100000
键名 功能键F1~F10 方向键↑ 方向键← 方向键→ 方向键↓ ON KEY(2) GOSUB pri KEY(2) ON S=0
For i=1 to 100000 S=S+i*i NEXT i
pring “s=”;s end
pri:print “now swm is”;s,”I=”;i return
(2).说明
设置陷阱:ON key(n) GOSUB <标号> 打开陷阱:KEY (n) on 关闭陷阱:KEY (n) off
三、独立模块的子程序 1、建立子程序
格式:SUB <子程序名>[(<参数表>)] ……… END SUB
2、子程序的调用
(1).格式
DECLARE SUB <子程序名>[(<参数表>)] ………
Call <子程序名>[(<参数表>)] 或 <子程序名> <参数表>
例:SUB stars(n)
for i=1 to n
PRINT “*”; Next i Print
END SUB
_________________________ DECLARE SUB Stars(n)
Call Stars(30) Call Stars(18) End (2). 说明
i)DECLARE 为外部子程序说明语句,主程序调用多少个子程序,就有多少个DECLARE语句;
ii)Call语句的“Call”可以省写,参数的括弧也可不写; 如: Call stars(30)可写成: stars 30
3、参数传递 (1).值传递方式
Call stars (30) ......
SUB stars (n) (2).地址传递方式
a=30
Call stars(a) ......
SUB stars(n) 例:求4!+5!+6!+7! 子程序:
SUB Fact(n,f) f=1
for i=1 to n
f=f*i next i
END SUB
主程序:DECLARE SUB Fact(n,f)
for i=4 to 7 Call Fact(i,f) S=S+f Next i
Print “s=”;S End
注:地址传递方式是当实际参数为变量时发生,它将可能会改变原变量的值,若实际参数是变量时,又不想用地址传递(即用值传递方式)则可把变量用括号括起来。 例:求两个整数的最大公约数和最小公倍数。最小公倍数=(m*n)/最大公约数 求最大公约数子程序:
SUB HCF(m,n,h)
IF m r=m MOD n LOOP h=n END SUB 求最小公倍数子程序: SUB LCM(m,n,h) h=m*n/h END SUB 主程序: DECLARE SUB HCF(m!,n!,h!) DECLARE SUB LCM(m!,n!,h!) INPUT \"m,n=\";m,n CALL HCF(m,n,h) PRINT \"最大公约数为:\";h CALL LCM(m,n,h) PRINT \"最小公倍数为:\";h END 说明:程序在执行时,结果不正确;其原因是CALL HCF语句调用时修改了m和n的值,以至使CALL LCM运行不正确。因此,CALL HCF语句应为: CALL HCF((m),(n),h) 例:验证哥德巴赫猜想:一个不小于6的偶数可以表示为两个素数之和。 算法: n=10 n1 n2 2(T) 8(F) 3(T) 7(T) n=16 n1 n2 2(T) 14(F) 3(T) 13(T) 四、模块化的函数 1、建立一个函数 FUNCTION <函数名>(<形参表>) ...... LET <函数名>=<表达式> END FUWSTION 2、函数的调用 与标准函数相同,只是在主程序开头加上 DECLARE FUNCTION <函数名>(<参数表>),无参数函数也要写上两个括号( ); 例:求4到7的阶乘之和 FUNCTION Fact(n) f=1 for i=1 to n f=f*i NEXT I Fact=f END FUNCTION __________ DECLARE FUNCTION Fact(n) S=0 For i=4 to 7 S=S+Fact(i) Next i Print \"S=\";S End 注意函数的参数传递 3、STATIC选项(静态) 外部函数中使用的变量,在函数调用结束后将全部被释放,其值不再保留。如要保留函数中的变量,可在建立函数时加写“STATIC”即 FUNTION 函数名(<参数>) STATIC 五、全局变量与局部变量 1、局部变量 每一个模块(子程序、主程序、函数)中的变量都只在本模块中有效,即是它们的作用域只限于模块,这种变量称为局部变量。 2、全局变量 在程序所有模块中都有效的变量,即作用域为整个程序变量称为全局变量。其定义格式为: COMMON SHARED <变量表> 六、过程的嵌套调用 在一个过程里又调用另一个过程。 七、过程的递归调用 在一个过程里又调用该过程本身; 例如直接调用: FUNCTION f(x) C=f(x) f=2*C END FUNCTION 又如交叉调用: FUNCTION f1(x) …… C=f2(y) …… f1=2*C …… FUNCTION f2(t) …… d=f1(a) …… f2=4/d …… END FUNCTION END FUNCTION 执行的结果造成无终止的自身调用,显然,程序中不应出现这种无终止的调用,而只应是有限次数的、有终止的递归调用。 FONCTION Age(n) If n=1 then Age=10 else Age=Age(n-1)+2 End FONCTION 主程序: DECLARE FUNCTION Age(n) Print Age(5) End FONCTION Fact(n) If n<=1 then Fact=1 else Fact=n*Fact(n-1) END FONCTION 第七章 数组 一、概念 例如要求一个班50名学生的平均成绩: 下标变量Si 用数组表示为:S(i) 1、有关说明: (1).数组与普通变量一样,用来存放数据; (2).数组中的数据必须是同一类型; 2、数组与循环结合 for i=1 to 50 input s(i) next i s=0 for i=1 to 50 s=s+s(i) next i print s/50 end 二、数组的建立和引用 1、数组的建立 (1).DIM <数组名>(下标上界) 或DIM <数组名>(上界1,上界2) 说明: ▪ 一般情况下,下标值从0开始 如:DIM A(5) 即定义了a(0)、a(1)、…、a(5); 若要修改下标起始值,可用下面语句: OPTION BASE N 如:OPTION BASE 1 DIM a(5) 则定义了5个变量a(1)、a(2)、a(3)、a(4)、a(5); 若数组下标上界不超过10则可不必用DIM定义数组。 (2)DIM <数组名>(n1 to n2) 下标值的范围:-32768~32767 ▪ 数组名与变量名的定义相同; ▪ 允许在同一模块中,数组名与变量名同名,它们不代表同一对象; DIM a(100) A=3 ▪ DIM语句中的上界可是常数或变量、表达式; 如: DIM a(10) DIM a(n) DIM a(n+2) 但变量值一定先赋值 ▪ 定义全局数组 DIM SHARED a(50) ▪ 用DIM 语句可定义变量类型 DIM <变量> AS <类型> 其中<类型>是:INTEGER(整型)、LONG(长整型)、SINGLE(单精度型)、DOUBLE(双精度型)、STRING(字符串型); 但<变量>不能加类型定义符,如下写法是错误的: DIM A& AS LONG 在用DIM语句定义了一个变量类型后,该变量名后面加上类型定义符或不加类型定义符都是合法的,且代表同一个对象。例如: DIM a AS LONG a=123456 a&=77777 print a , a& END 运行结果如下: 77777 77777 但程序中不能再用a作其它类型的变量名。 2、数组的引用 ▪ 引用数组元素(下标变量),即在括弧中指定下标; ▪ 在程序中,数组与其它变量的使用相同,即可参与运算,可以被赋值; ▪ 在引用数组时,数组名、类型、维数以及下标的范围,应与定义时一致; ▪ 同一模块中,数组和变量可同名,但数组与数组不能同名; 下列情况是不允许的: DIM a(10,10) 或 DIM a(50,50) DIM a(15) DIM a%(15) 3、静态数组和动态数组 静态数组——建立数组后,其维数和大小不能改变; 动态数组——在程序执行教程中,可改变大小或者被释放; QBASIC规定:在DIM 语句中用常数指定下、上界的数组为静态数组,如果用变量(或表达式)指定上下界的数组为动态数组。 (1).重定义语句 REDIM <数组名>(上界) 如:DIM S(20),X(20,30) …… √REDIM S(50) ×REDIM X(30) 只改变同名数组的大小,但不能改变维数; (2).释放数组语句 ERASE <数组名> 释放数组所占据的空间; 例1:释放和重定义数组: n=10 DIM a(n) FOR i=1 TO n a(i)=i PRINT a(i); NEXT i PRINT ERASE a REDIM a(16) FOR i=1 TO 16 a(i)=i PRINT a(i); NEXT i PRINT END 说明: .如果不使用ERASE语句释放数组,不能用DIM语句对同一个数组两次定义; .用REDIM可改变数组的大小,而不必先用ERASE语句释放数组; .无论用DIM或REDIM定义一个与原来数组同名的数组,可以改变数组中各维的上下界,而不能改变数组的维数。 (3).数组上、下界函数 LBOUND(<数组名>,<维数>)——下界函数 UBOUND(<数组名>,<维数>)——上界函数 例: INPUT n,m DIM a(n TO m) FOR i=LBOUND(a,1) TO UBOUND(a,1) a(i)=i PRINT a(i); NEXT i PRINT DIM b(10,15) FOR i=1 TO UBOUND(b,1) FOR j=1 TO UBOUND(b,2) b(i,j)=10*i+j PRINT b(i,j); NEXT j NEXT i PRINT END 三、数组的应用 1、一维数组 只有一个下标的数组。 (1).数据统计 例: 输入n个学生的成绩,求平均成绩。 OPTION BASE 1 INPUT \"number of students is:\";n DIM s(n) FOR i=1 to n INPUT s(i) sum=sum+s(i) NEXT i aver=sum/n PRINT \"aver=\";aver END 例: 输入n个学生的学号和成绩,要求输出平均成绩和高于平均分的学生学号及成绩。 OPTION BASE 1 INPUT \"number of students is:\";n DIM num(n),score(n) FOR i=1 to n INPUT num(i),score(n) sum=sum+score(i) NEXT i aver=sum/n PRINT PRINT \"平均分是:\";aver PRINT PRINT \"高于平均分的学生有:\" PRINT \"学号\成绩\" FOR i=1 TO n IF score(i)>aver THEN PRINT num(i),score(i) NEXT i END (2)、数据排序 例:从键盘输入10个数。要求按由小到大的顺序将它们打印出来; 比较交换法 a1、a2、a3、a4、a5、a6、a7、a8、a9、a10 第一次:a1与a2、a3、a4、a5、a6、a7、a8、a9、a10比较 第二次:a2与a3、a4、a5、a6、a7、a8、a9、a10比较 第三次:a3与a4、a5、a6、a7、a8、a9、a10比较 第四次:a4与a5、a6、a7、a8、a9、a10比较 第五次:a5与a6、a7、a8、a9、a10比较 第六次:a6与a7、a8、a9、a10比较 第七次:a7与a8、a9、a10比较 第八次:a8与a9、a10比较 第九次:a9与a10比较 OPTION BASE 1 DIM a(10) FOR i=1 TO 10 INPUT a(i) NEXT i FOR i=1 TO 9 FOR j=i+1 TO 10 if a(i)>a(j) THEN SWAP a(i),a(j) NEXT j NEXT i FOR i=1 TO 10 PRINT a(i); NEXT i END 6. 选择法 OPTION BASE 1 DIM a(10) FOR i=1 TO 10 INPUT a(i) NEXT i FOR i=1 TO 9 k=i FOR j=i+1 TO 10 if a(k)>a(j) THEN k=j NEXT j if k<>i THEN SWAP a(k),a(i) NEXT i FOR i=1 TO 10 PRINT a(i); NEXT i END (3).数据查找(检索) 例: 设有n个学生,每个学生的数据包括:学号、姓名、性别、年龄、平均分等;要求输入一个学号,程序输出该学生的所有数据。 • 顺序查找法 假设:num(i)为学生学号,nam$(i)为姓名,num为查找对象。 SUB Search FOR i=1 TO n IF num=num(i) THEN PRINT \"num\";num(i) PRINT \"name\";nam$(i) EXIT FOR END IF NEXT i IF i>n THEN num ;\"not found\" END SUB • 折半查找法(二分查找法); 对按一定规律(由小到大或由大到小)排列好的数据进行检索;假设:num(i)为按从小到大排列的学生学号,nam$(i)为姓名,num为查找对象。 SUB Search top=1 bot=n find=0 DO mid=INT((top+bot)/2) IF num=num(mid) THEN PRINT \"num\";num(i) PRINT \"name\";nam$(i) find=1 ELSEIF num LOOP UNTIL ((bot aij——双下标变量 a(i,j)→二维数组 数组定义:DIM A(m,n) a(i,j)→b(j,i) 例: 输出魔阵——每行、每列和对角线之和均相等。 排列规律: (1)、先将“1”放在第一行当中; (2)、从“2”开始到N*N止,各数中每一个数存放的行比前一个数的行数减1,列数加1; (3)、如果上一个数的行数为1,则下一个数的行数为n(最后一行); (4)、当上一个数的列数为n时,下一个数的列数为1,行数减1; (5)、如下一个数应放的位置已被其它数占据,则下一个数放在上一个数的下面。 四、过程中的数组参数 1、作为下标变量 子程序定义:SUB A(x,y) …… END SUB 调用:DIM T(10) …… Call A(t(1),t(2)) 2、作为数组: 定义 : 调用 CALL B(p(),g()) 将主程序中的P、G传给子程序中的a,b 数组传递采取“地地传递”方式。即子程序中对形象参值的修改,将会改变实参值; 第八章 字符串处理 字符串——字符系列 一、字符串常量 1、显式常量 • 用双引号括起来的一串字符(不包括双引号); • 空格也是一个字符,没有字符的字符串叫空串\"\"; • 数值常量与字符串常量的分别。 123表示一个数值常量,而\"123\"表示一个字符串常量 2、符号常量 用一个符号名(字母)代表一个字符串常量; 如:CONST c=\"Beijing\" CONST c$=\"Beijing\" 注意:字串常量与字串变量的区别,字串常量是不能改变的; CONST c$=\"Shanghai\"不正确。 二、字符串变量 1、变长字符串变量 长度在0-32767范围; (1)定义方法 ①变量名后加类型说明符“$”; ②用DEFSTR语句; 如;DEFSTR a,b 以a和b开头的变量均为字串; ③用DIM语句; 格式:DIM <变量名> AS STRING 变量名不应包含类型说明符; (2)说明 ①变量名不分大小写; ②变量名应避开关键字; 2、定长字符串变量 格式;DIM <变量名> AS STRING*n; n为字符串长度; 如:DIM NAM AS STRING*20 DIM A AS STRING*10,B AS STRING *20 在对定长字串变量赋值时,如果实际长度小于定义个数,则字符一律靠左存放,右端补空格; 三、字符串变量的赋值 1、用LET语句 [LET] <变量名>=<字符串> 例 用LET语句给字符串变量赋值。 DIM a AS STRING LET a=\"This is a BASIC program\" PRINT a END 2、用INPUT语句 输入时字符串用引号或不用引号的区别: ①如果字符串首尾有空格,不用引号时,空格将被舍弃; ②如果输入的字符串有逗号,则一定要有引号。 3、用LINE INPUT 语句 行输入语句:输入一行以回车结束,中间可以是任何字符,不显示\"?\"号; 例 用LINE INPUT语句给字符串变量赋值。 PRINT \"enter 2 lines:\" LINE INPUT a$ LINE INPUT b$ PRINT a$,b$ END 4、用READ/DATA语句 READ语句中可包含数值变量和字符串变量,而DATA语句中只能相应放置数值常量和字符常量。 例 用READ/DATA语句给字符串变量赋值。 DEFSTR a READ a1,a2,a3,s1,s2,s3 PRINT a1,s1 PRINT a2,s2 PRINT a3,s3 DATA \"Basic\END 四、字符串的连接 两个字符串的合并,运算符为“+” 例 字符串连接。 a$=\"China\" b$=\"The People's Republic of \" c$=\"I love\" d$=b$+a$ PRINT d$ PRINT c$+a$ END 五、字符串的比较 1、字符比较规则 用字符的ASCⅡ代码的大小进行比较(见课本附表P353-355),常用的字符顺序如下(由小到大): 空格 ! \" # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \\ ] ^ _ 、a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ 中文字。 2、字符串比较的规则 两个字串从左到右逐个字符比较。 \"BASIC\"=\"BASIC 但 \" BASIC\"< >\"BASIC\" 3、字符关系表达式 两字符串的比较结果(真假值); 六种关系运算符:= , <, <> ,> ,<=, >= 。 六、字符串数组 与数值数组的定义相类似。 七、字符串函数 八、字符串处理 第九章 屏幕控制和作图 一、显示模式 显示模式:信息在屏幕上的显示方式。 1、文本模式 屏幕上显示的最小单位为一个字符,这种模式下的用户不能用线条来绘制各种图形只能用字符组合成粗糙的图案。 在这种模式下屏幕分为25行,每行80个字符。 屏幕左上角为原点坐标,坐标为(1,1)。 2、图形模式 屏幕上显示的最小单位是显示器的象素点,可用基本的几何图形,如直线、方框、圆等绘制出复杂而精美的图画。 这种模式在VGA以上显示器的显示范围为640×480点,原点坐标(0,0)在屏幕左上角。 二、屏幕控制语句 1、LOCATE语句 格式:LOCATE [<行>],[<列>] 功能:确定光标在屏幕上的坐标位置。 说明:取值范围:行1-25,列1-80 例如: LOCATE 10,10 PRINT “QBASIC” LOCATE 15,10 PRINT “再见” 2、WIDTH语句(设置输出的行宽) 格式:WIDTH <宽度值> 功能:确定屏幕输出宽度。 其中:宽度的有效值是40或80 例如: WIDTH 40 字符是扁形 WIDTH 80 字符是长形 3、CLS语句 格式:CLS 功能:清除屏幕信息,确定光标位置:在文本方式下,将光标置于屏幕的左上角,在图形方式下,将光标置于屏幕的中心。 4、CSRLIN和POS函数 格式:CSRLIN POS(n) 功能:CSRLIN 记录光标所在的行位置。 POS 记录光标所在的列位置。 例: LOCATE 5,7 A = CSRLIN B = POS(0) LOCATE 10,15 PRINT“ABCD” PRINT A,B 5、SCREEN语句 格式:SCREEN [<模式>],[<色彩>] 功能:设置屏幕的显示方式(文本或图形) 其中:“模式”代表显示器的工作方式 “色彩”是一个数值表达式,只有在模式为0、1和2时它才有效。 显示模式:0-13(除5和6外)有12种图形模式可供使用。(参见P296表11.3) 色彩:0,1,2,三种(参见P297表11.5) 例:SCREEN 0,0 模式为0,彩色为0 表示屏幕工作在黑白字符模式下。 6、COLOR语句 功能:设置屏幕显示的颜色 (1)、设置文本方式的屏幕显示颜色 格式:COLOR <前景色>,<背景色> <前景色>:定义屏幕上所显示的字符颜色 数值范围是0-31,如P298表11.6表示0-15 共16种颜色,16-31是在0-15基础上加16为闪烁方式。 <背景色>:定义屏幕的底色,数值范围为0-7. (2)、 设置模式1的屏幕显示颜色 格式:COLOR <背景色>,<配色器号> <配色器号>:0和1号配色器 它们有四种颜色,见P299表11.8 例如: COLOR 2,1 背景绿色1号配色器 (3)、设置图形模式12-13的显示颜色 格式:COLOR [<前景色>] 例:显示模式12的16种前景颜色。 CLS SCREEN 12 FOR I=0 TO 15 COLOR I PRINT \"*** Current Color is \" I;\"***\" NEXT I END 例:动态显示文字。 三、作图语句 1、画点 (1)、PSET(x,y)[,<色彩>] 功能:在屏幕上指定的坐标位置画一个点 说明:(x,y)为坐标点,如屏幕模式为12时,x为0-639,y为0-479 <色彩>:画点的颜色,缺省时用前景色。 例:画一点。 SCREEN 1,0 COLOR 7,0 PSET(160,100) 例:画一连线。 SCREEN 1,0 FOR i = 1 TO 300 PSET(i,100),2 NEXT 例:从(1,1)到(199,199)画一斜线。 CLS SCREEN 1,0 FOR i = 1 TO 199 PSET (i,i),2 NSET i (2)、PRESET(x,y)[,<色彩>] 功能:作用相同PSET,区别是省略色彩时,用背景色画点,可用它擦去位于(x,y)的点。 (3)、STEP (X,Y)表示相对坐标 PSET STEP (x,y),<彩色> PRESET STEP (x,y),<彩色> PSET(10,10) PSET STEP(10,10) PSET STEP(10,10) 2、画线 (1)、LINE语句 格式:LINE (x1,y1)-(x2,y2),<彩色>[,B|BF] 功能:在屏幕上指定的位置画一直线或矩形。 说明:(x1,y1)为直线的起始坐标, (x2,y2)为直线的终点, <彩色>指定直线的颜色, B的作用是画一个以坐标(x1,y1)到(x2,y2)为对角线的矩形框; BF不仅画一个矩形框,而且在框内填满与边相同的颜色。 2)、DRAW语句(连续画线语句) 格式:DRAW <字符串> 功能:在屏幕上连续画出各种直线 说明:<字符串>Un 向上移动n个单位 Dn 向下移动n个单位 Ln 向左移动n个单位 Rn 向右移动n个单位 En 向右上方移动n个单位 Fn 向右下方移动n个单位 Gn 向左下方移动n个单位 Hn 向左上方移动n个单位 Cn 选择颜色n Sn 比例图示 An 把图形旋转一个角度,n的数值为0、1、2、3(0表示不转,1逆时针转90,2为逆时针转180,3为逆时针转270度) Mx,y 从当前位置开始向(x,y)画线 3、画圆语句 (1)、画圆 格式:CIRCLE(x,y),<半径>[,<色彩>] 功能:以指定的圆心和半径画一个圆。 说明:(x,y)为圆心坐标,<半径>为所要绘制圆的半径;<色彩>为绘制的圆指定颜色。 例:以(200,150)为圆心,以50为半径画一个圆。 CLS SCREEN 12 CIRCLE(200,150),50 END (2)、画椭圆 RCLE(x,y),半径[,<色彩>],,<纵横比>说明:<纵横比>:小于1时,椭圆为横向,大于1时,椭圆为竖向,若不指定,默认为1(即画圆)。 (3)、画圆弧 CIRCLE(x,y),半径[,<色彩>],<起始角>,<终止角> 其中<起始角>和<终止角>为所画圆弧的起始位置和终止位置,以逆时针方向,度量单位为弧度,取0-2pi。 四、图形着色 格式:PAINT (X,Y)[,<填充色>[,<边界色>]] 功能:对封闭图形进行着色。 五、图形窗口 1、WINDOW语句 (1)、WINDOW (X1,Y1)-(X2,Y2) 定义一个标准的坐标系,Y轴向上。 (2)、WINDOW SCREEN (X1,Y1)-(X2-Y2) 定义一个标准的坐标系,Y轴向下。 一旦定义了一个新的坐标系(逻辑坐标系),程序中的图形语句都将使用此坐标系的坐标值作图;当WINDOW后无参数时,返回屏幕坐标系统。 2、VIEW语句 格式:VIEW [SCREEN] (X1,Y1)-(X2,Y2),<底色>,<边界色> 定义一个矩形区域,使制作的图形仅限在这个区域内输出,称这个区域为视窗。 SCREEN的选用将保持原来系统提供的屏幕绝对坐标,即物理屏幕坐标,原点在左上角。 第十章 文件 文件——程序或数据存放在磁盘上的形式,存放在外部介质上的数据的集合; 程序——文件 数据 ——文件 一、文件的概念 1、分类 (1)从文件的内容区分; • 程序文件——源程序或可执行的目标程序 • 数据文件——输入/输出数据; (2)从文件的存储形式区分; • ASCⅡ文件(文本文件) 源程序、字符串数据可用TYPE命令显示; 存储时需转换ASCⅡ——二进制形式; • 二进制文件 用二进制形式存储 (3)从文件的组织形式区分; • 顺序文件(不定长) • 随机文件(定长) 2、文件与记录 一个文件是由若干个记录组成,一个记录包含若干个数据项。 例如一个学生的数据:学号、姓名、年龄、成绩等可看成一组数据组成一个记录; 3、文件名 扩展名:.BAS、.FOR、.PAS、.C 4、文件的读写和文件缓冲区 读文件——将文件读入内存,或将文件读入计算机。 写文件——从计算机主机向磁盘传送(输出)数据。 对磁盘上的数据文件进行读写操作时,必须在内存中开辟一个“文件缓冲区”,以建立必要的输入/输出通道。 5、文件指针 每文件都有一个指针,指向当前应读写的位置,从文件中读数据,就是读指针所指向位置处的数据。向文件写数据,是写到指针所指向的位置处。 二、顺序文件 1、概念 顺序存取文件(SEQIEMCE ACCESS FILE) ——文件中各记录写入顺序,存放的顺序和读出的顺序三者是一致的。 记录1 …… 记录i …… 记录n 2、顺序文件的打开与关闭 使用之前,先“打开”文件,使用后“关闭”它; (1).OPEN 语句 格式:OPEN <文件名> FOR <读写方式> AS#<文件号> <读写方式>: • OUTPUT:写数据,向文件输出; • INPUT:读数据,从文件读入; • APPEND:写数据:添加记录; <文件号>:即文件缓冲区号,每一个文件都要指定一个不同的文件号(1~225); 说明: • 以OUTPUT方式打开文件,建立新文件,指针指向首记录;将删除已存在的文件。 • 以INPUT方式打开已存在的文件,指针指向首记录; • 以APPEND方式打开文件,指针指向文件尾;可建立新文件 (2)CLOSE语句 关闭已用的文件 CLOSE [#<文件号1>][,#<文件号2>]…… 关闭由文件号指定的文件缓冲区,将内容存盘,如不指定文件号,则关闭所有已打开的文件; 3、输出数据(写文件) 新文件写入记录 (1)PRINT#语句 格式:PRINT #<文件号>,<输出项> 例;PRINT #1,a;b;c 注意:逗号与分号的差别,与PRINT语句类似在对字符串存盘时,注意引入定界符。 (2)WRITE#语句 存盘时,各数据间插入逗号,并给字串加双引号,且正数前面不设空格。 例: OPEN \"student.dat\" FOR OUTPUT AS #1 READ num,nam$,sex$,score DO UNTIL nam$=\"end\" WRITE #1,num,nam$,sex$,score READ num,nam$,sex$,score LOOP DATA 101,Li,m,90,103,Wang,f,98 DATA 104,Xiu,f,100,105,Zhang,m,78 DATA 107,Tan,m,99,109,Ling,f,88 DATA 000,end,, END 说明:(1)、文件中的记录以:“回车换行符”相隔: CHR$(13)、CHR$(10) (2)、文件最后用“文件结束符”结束CHR$(26) 一个记录的长度不能超过225个字符; (3)、PRINT#与WRITE#的区别: • WRITE#语句(数据项之间用“,”或“;”均相同) 101,\"Li\103,\"Wang\ • PRINT#语句(数据项之间用“;”) 101 Lim 90 103 Wangf 98 • PRINT#语句(数据项之间用“,”) 101 Li m 90 103 Wang f 98 4、输入数据(读文件) 从已建立文件中读入数据到计算机中; (1)INPUT#语句 格式:INPUT #<文件号>,<变量1>[,<变量2>…..] 每次从文件中读出一个记录, 注意:变量类型应与数据一致; 例: OPEN \"student.dat\" FOR OUTPUT AS #3 DO INPUT #3,num,nam$,sex$,score PRINT num,nam$,sex$,score LOOP UNTIL EOF(3) CLOSE END 终止函数 EOF(<文件号>) 检查记录指针是否指向文件尾,是则真(-1),否则为假(0) (2)LINE INPUT#语句 格式:LINE INPUT#<文件号>,<字串变量> 将文件的记录,以字符形式读入; 例: OPEN \"student.dat\" FOR OUTPUT AS #3 DO LINE INPUT #3,stud$ PRINT stud$ LOOP UNTIL EOF(3) CLOSE END 5、文件的修改 若要修改已有的顺序文件,则要利用中间文件,因为对一个顺序文件不能既读又写。对顺序文件的修改步骤: (1)、用INPUT方式打开需要修改的旧文件,准备从中逐个读出数据; (2)、另设一个中间临时文件(用OUTPUT方式打开),用来存放修改后的各记录; (3)、逐个读入旧文件的记录,用户决定是否修改?如果不改,就把此记录原封不动地写到中间文件中去;如果要修改,则在修改后再写到中间文件中。 (4)、将旧文件删除,把中间文件改名为原来的旧文件的名称。 例: OPEN \"student.dat\" FOR INPUT AS #1 OPEN \"temp\" FOR OUTPUT AS #2 DO UNTIL EOF(1) INPUT #1,num,nam$,sex$,score PRINT num,nam$,sex$,score INPUT \"chang?(y/n)\";r$ if UCASE$(r$)=\"Y\" THEN INPUT num,nam$,sex$,score WRITE #2,num,nam$,sex$,score INPUT \"insert?(y/n)\";q$ if UCASE$(q$)=\"Y\" THEN INPUT num,nam$,sex$,score WRITE #2,num,nam$,sex$,score END IF LOOP CLOSE KILL \"student.dat\" NAME \"temp\" AS \"student.dat\" END 6、有关函数和语句 • EOF()函数 尾测试 • INPUT$()函数 格式:INPUT$(<字节数>,<文件号>) 从指定的打开文件中读取指定数目的字符; • LOF()函数 给出指定文件已进行读写的字节数; 格式:LOF(<文件号> • SEEK()函数 格式:SEEK(<文件号>) 给出指定文件的当前指针 • SEEK语句 指针移动 格式:SEEK#<文件号>,<字节位置> 有关顺序文件的语句和函数:P336表12.7 三、随机文件(RAMDOM ACCESS FILE) 随机存取文件——所有记录等长,各记录相应的数据项的长度也相同; 按记录号进行存取,记录的顺序不一致,可直接读写任一条记录。 1、随机文件的建立 (1)OPEN <文件名> AS#<文件号> [LEN=<长度>] 存取方式不用指定,自动加上“FOR RANDOM”,表示随机文件; (2)定义缓冲区中各“域”的长度(FIELD 字段) FIELD <文件名>,<域宽>AS<域名>[,<域宽>AS <或名>] 定义记录的结构 如:FIELD #1, 10 AS A$, 15AS B$, 36AS C$ (3)随机文件的记录中各域只能存放字符串数据,在对数值型数据进行处理时,要经过转换; (4)数值转换为字符的函数 MKI$(<整型表达式>) 2字节 MKS$(<单精度表达式>) 4字节 MKD$(<双精度表达式>) 8字节 称为“内码字符串” (5)缓冲区中各域的字符串变量赋值 LSET <域变量>=<字符串>(左对齐) RSET <域变量>=<字符串>(右对齐) (6)将文件缓冲区中的数据存盘 PUT #<文件号>[,<记录号>] (7)用CLOSE关闭文件 例: OPEN \"good.dat\" FOR RANDOM AS #1 LEN=23 FIELD #1, 2 AS n$,15 AS m$,4 AS P$,2 AS s$ DO READ num%,nam$,price,stock% IF num%=9999 THEN EXIT DO LSET n$=MKI$(num%) LSET m$=nam$ LSET p$=MKS$(price) LSET s$=MKI$(stock%) PUT #1 LOOP DATA ............. DATA ............. DATA ............. DATA ............. DATA ............. DATA 9999,,, CLOSE END 2、随机文件的读入 (1)、打开随机文件 OPEN <文件名> AS#<文件号> [LEN=<长度>] (2)、定义文件缓冲区中各域的长度; FIELD <文件名>,<域宽>AS<域名>[,<域宽>AS <或名>] (3)、从指定的文件中读取一个记录 GET #<文件号> [,<记录号>] (4)、将内码字符串还原为数值型数据; CVI(<2个字节的域变量>)——整数 CVS(<4个字节的域变量>)——单精度 CVD(<8个字节的域变量>)——双精度 这三个函数是MKI$,MKS$ MKD$的逆运算 (5)、关闭文件 CLOSE 例: OPEN \"good.dat\" FOR RANDOM AS #1 LEN=23 FIELD #1, 2 AS n$,15 AS m$,4 AS P$,2 AS s$ PRINT \"num\FOR i%=1 TO LOF(1)/23 GET #1,i% num%=CVI(n$) nam$=m$ price=CVS(p$) stock%=CVI(s$) PRINT num%,nam$,price,stock% NEXT i% CLOSE END 3、随机文件的修改 随机文件的优点:可直接读写任何一个记录,且既能读又能写。 例: OPEN \"good.dat\" FOR RANDOM AS #1 LEN=23 FIELD #1, 2 AS n$,15 AS m$,4 AS P$,2 AS s$ INPUT \"which record:\";r DO UNTIL r=0 GET #1,r num%=CVI(n$) nam$=m$ price=CVS(p$) stock%=CVI(s$) PRINT num%,nam$,price,stock% INPUT \"price=\";price LSET p$=MKS$(price) PUT #1,r INPUT \"which record:\";r LOOP CLOSE END 3、记录型变量 一个记录包括若干个“域”,在同一文件中各个记录所包含的域都是相同的,这样可以定义一种新的变量类型——记录。 1001 1002 1003 Shirt Skirt Coat 67 87 231.5 120 108 67 (1)、定义记录类型 格式:TYPE <记录类型名> <域名1> AS <类型> <域名2> AS <类型> ...... <域名n> AS <类型> END TYPE 例如: TYPE goods num AS INTEGER nam AS STRING*15 price AS SINGLE stock AS INTEGER TYPE END (2)、定义记录变量 格式: DIM <记录变量名> AS <记录类型名> 例如: DIM a AS goods (3)、记录变量中的域表示法 格式: <记录变量名>.<域名> 例如: a.num 表示a变量中的num域。 4、用于记录变量的读写语句 (1)、GET#语句 格式:GET #<文件号> [,<记录号>][,<记录变量>] 功能: 用于从文件中读一个指定的记录,赋给一个记录变量。 (2)、PUT#语句 格式:PUT #<文件号> [,<记录号>][,<记录变量>] 功能: 将一个记录变量的内容写到指定的记录中去。 例10-8:用记录变量的方法建立一个随机文件。 (P346例12.14) TYPE goods num AS INTEGER nam AS STRING*15 price AS SINGLE stock AS INTEGER TYPE END DIM cloth AS goods OPEN \"good.dat\" FOR RANDOM AS #1 LEN=LEN(cloth) DO READ cloth.num,cloth.nam,cloth.price,cloth.stock IF cloth.num=9999 THEN EXIT DO PUT #1,,cloth LOOP DATA ..... ..... DATA 9999,,, CLOSE END 例:用记录变量的方法读入一个随机文件内容。 TYPE goods num AS INTEGER nam AS STRING*15 price AS SINGLE stock AS INTEGER TYPE END DIM cloth AS goods OPEN \"good.dat\" FOR RANDOM AS #1 LEN=LEN(cloth) PRINT \"num\FOR i%=1 TO LOF(1)/LEN(cloth) GET #1,i%,cloth PRINT cloth.num,cloth.nam,cloth.price,cloth.stock NEXT i% CLOSE END 例:用记录变量的方法修改一个随机文件内容。 TYPE goods num AS INTEGER nam AS STRING*15 price AS SINGLE stock AS INTEGER TYPE END DIM cloth AS goods OPEN \"good.dat\" FOR RANDOM AS #1 LEN=LEN(cloth) DO INPUT \"which record\";r IF r=0 THEN EXIT DO GET #1,r,cloth PRINT cloth.num,cloth.nam,cloth.price,cloth.stock INPUT \"price=\";cloth.price PUT #1,r,cloth LOOP CLOSE END 四、文件与目录处理 1、显示磁盘目录 FILES [\"文件名\"] 例:FILES \"*.BAS\" —显示当前目录下,扩展名为BAS的所有文件; 2、执行DOS命令 SHELL [命令字符串] 例:SHELL \"dir\" — 暂时退出QBASIC,执行DOS的命令dir(显示目录),然后返回QBASIC。 注:如果没有[命令字符串],则转到DOS命令状态,可用EXIT返回QBASIC。 3、文件改名 NAME <旧名> AS <新名> 可改名或修改文件路径。 4、文件删除 KILL <文件名> 5、目录操作 MKDIR <路径名>——建立子目录 CHDIR <路径名>——改变当前目录 RMDIR <路径名>——删除(空)目录 因篇幅问题不能全部显示,请点此查看更多更全内容