主题:回MOZ;求助
w1212q
[专家分:660] 发布于 2006-11-30 16:37:00
DECLARE SUB Split (X$(), y2$, z$)
DECLARE SUB MiddleCode (Code AS STRING)
SCREEN 12
ON ERROR GOTO ErrCode
DIM TucCode AS STRING
DO
INPUT "", TucCode
TucCode = LCASE$(TucCode)
MiddleCode TucCode
LOOP
END
ErrCode:
PRINT "ErrorCode"
PRINT "Key Enter To Exit"
DO
LOOP UNTIL INKEY$ = CHR$(13)
END
SUB MiddleCode (Code AS STRING)
DIM SplitCode(LEN(Code)) AS STRING
DIM Codetmp AS STRING
IF LEN(Code) = 0 THEN EXIT SUB
SELECT CASE MID$(Code, 1, 1)
CASE "*"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "* ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d * VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "+"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "+ ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d + VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "-"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
PRINT "- ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d - VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "\"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "\ ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d \ VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "%"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "% ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d MOD VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "/"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "/ ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d / VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "^"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "^ ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d ^ VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "~"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "~ ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d XOR VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "@"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "@ ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d OR VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "#"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "# ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
d = d AND VAL(SplitCode(a))
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
CASE "&"
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
SELECT CASE Codetmp
CASE "0"
END
CASE "1"
CLS
END SELECT
END SELECT
END SUB
SUB Split (X$(), y2$, z$)
y$ = y2$ + z$
l% = LEN(z$)
i% = INSTR(y$, z$)
j% = 1
DO WHILE i%
K% = K% + 1
X$(K%) = MID$(y$, j%, i% - j%)
j% = i% + l%
i% = INSTR(j%, y$, z$)
LOOP
X$(0) = STR$(K%)
END SUB
上面的程序是个计算的;
运行还正常;
只是输入错误;
列如输入 *['as'ss's;
等不规则表达式时;
程序就有错误;
我想在MiddleCode过程设置错误陷阱;
可是QB提示错误信息;
所以我只能在在主过程里设置陷阱;
每次输入错误都要退出;烦;
回复列表 (共15个回复)
沙发
moz [专家分:37620] 发布于 2006-11-30 20:11:00
1. 注意多些使用rtrim$(ltrim$())或VB里的trim()
2. 你的错误捕获语句还不如不设,
那样的话还可以提示你在哪里出错。
3. SUB MiddleCode 里有太多的冗余代码,
同样的功能同样的处理应该用同一个路口。
例如:
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT "# ";
FOR a = 1 TO VAL(SplitCode(0))
4. 你既然知道“不规则表达式时;程序就有错误;”
那么你就应该想办法怎么检测这样的错误,
怎样避免这样的错误,怎样处理这样的错误。
比如说没有左括号该怎办,没有右括号该怎办。
分出来的字符串不是有效数值该怎办。
板凳
w1212q [专家分:660] 发布于 2006-12-01 11:34:00
好建议;
'------------------------------
DECLARE SUB TiGui (Max AS INTEGER, Man AS INTEGER)
DECLARE SUB Split (x$(), y2$, z$)
SCREEN 12
CONST TRUE = -1
CONST FALSE = 0
DIM Code AS STRING
DO
INPUT "", Code
Code = LCASE$(Code)
REDIM Dm(LEN(Code)) AS STRING
Split Dm(), Code, " "
TiGui VAL(Dm(1)), VAL(Dm(2))
LOOP UNTIL LCASE$(Code) = "end"
SUB Split (x$(), y2$, z$)
y$ = y2$ + z$
l% = LEN(z$)
i% = INSTR(y$, z$)
j% = 1
DO WHILE i%
k% = k% + 1
x$(k%) = MID$(y$, j%, i% - j%)
j% = i% + l%
i% = INSTR(j%, y$, z$)
LOOP
x$(0) = STR$(k%)
END SUB
SUB TiGui (Max AS INTEGER, Man AS INTEGER)
STATIC TMax AS INTEGER
STATIC TMan AS INTEGER
TMax = Max: TMan = Man
IF TMan >= TMax THEN
PRINT TMan
TMan = TMan - 1
TiGui TMax, TMan
END IF
END SUB
'-------------------------
上面的程序是输入两个数来模拟循环的
列;
1 30
输出:
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
一般的数还可以承受;
但是两数的差大于100就不行了,QB提示 Out of stack spaec
3 楼
moz [专家分:37620] 发布于 2006-12-01 17:48:00
QB里的堆栈空间很有限的,
可以用命令扩充堆栈空间,但很危险,也不方便.
在QB里不建议使用过多的递归,建议<20次.
具体次数与你函数(或过程)中使用的变量空间有关.
4 楼
w1212q [专家分:660] 发布于 2006-12-05 16:28:00
哪怎样解决上面的问题;
总不能PRINT “ERROR”吧;
5 楼
moz [专家分:37620] 发布于 2006-12-05 16:56:00
大部份错误是可以在编程阶段中解决的,
而不必要等到出现不明错误的时候来做,
而且你也不一定知道是什么错.
关于反复递归调用的堆栈溢出问题,溢出的只是QB的问题
建议使用更高级的编程工具,可以很好的避免问题.
事必要用QB的话,可以用数组代替,
我曾发过此类贴,很旧了,关键字:"递归","数组"
6 楼
w1212q [专家分:660] 发布于 2006-12-06 16:42:00
我现在有一个VBDOS;
不知有什么限制;
7 楼
w1212q [专家分:660] 发布于 2006-12-06 16:43:00
怎样有数组剃归啊;
8 楼
moz [专家分:37620] 发布于 2006-12-06 21:41:00
VBDOS也就是VB1.0
都是DOS下的编程工具,
具体堆栈空间我没测试过不太清楚,
估计会有改进。
至于数组怎样替代递归,你可以想像一下,
递归的原理是怎样的?
1. 保存现场,可进可退。
2. 跳进新套,得出结果。
3. 返回旧套,恢复现场。
知道哪些变量需要怎样记录,
哪些变量需要怎样恢复和处理,
因为数量太多,用数组实现就可以了。
缺点,你的脑袋结构需要一点复杂程度,
你需要记得哪个位置怎样用哪个位置怎样恢复。
一般人无法正常理解。
9 楼
w1212q [专家分:660] 发布于 2006-12-07 16:29:00
QB的问题;
感谢你的提议;
现以改进;
DECLARE SUB Split (X$(), y2$, z$)
DECLARE SUB MiddleCode (Code AS STRING)
SCREEN 12
DIM TucCode AS STRING
LOCATE 30, 1
PRINT "WodeDm Remede +,-,*,\,/,%,^,~,@,# ; p[y;y...;n] ; &[0] End &[1] Cls"
LOCATE 1, 1
VIEW PRINT 1 TO 27
DO
INPUT "", TucCode
TucCode = LCASE$(TucCode)
MiddleCode TucCode
LOOP
END
SUB MiddleCode (Code AS STRING)
DIM SplitCode(LEN(Code)) AS STRING
DIM Codetmp AS STRING
IF LEN(Code) = 0 THEN EXIT SUB
SELECT CASE MID$(Code, 1, 1)
CASE "*", "+", "-", "\", "/", "%", "^", "~", "@", "#"
GOSUB MCode
CASE "&"
IF INSTR(Code, "[") <> 0 AND INSTR(Code, "]") <> 0 THEN
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
SELECT CASE Codetmp
CASE "0"
END
CASE "1"
CLS 2
END SELECT
END IF
END SELECT
EXIT SUB
MCode:
IF INSTR(Code, "[") <> 0 AND INSTR(Code, "]") <> 0 THEN
Codetmp = MID$(Code, INSTR(Code, "[") + 1)
Codetmp = MID$(Codetmp, 1, INSTR(Codetmp, "]") - 1)
Split SplitCode(), Codetmp, ";"
PRINT MID$(Code, 1, 1) + " ";
FOR a = 1 TO VAL(SplitCode(0))
PRINT SplitCode(a) + " ";
NEXT
PRINT
d = VAL(SplitCode(1))
FOR a = 2 TO VAL(SplitCode(0))
SELECT CASE MID$(Code, 1, 1)
CASE "+"
d = d + VAL(SplitCode(a))
CASE "-"
d = d - VAL(SplitCode(a))
CASE "*"
d = d * VAL(SplitCode(a))
CASE "\"
d = d \ VAL(SplitCode(a))
CASE "/"
d = d / VAL(SplitCode(a))
CASE "^"
d = d ^ VAL(SplitCode(a))
CASE "~"
d = d OR VAL(SplitCode(a))
CASE "@"
d = d XOR VAL(SplitCode(a))
CASE "#"
d = d AND VAL(SplitCode(a))
END SELECT
NEXT
Codetmp = STR$(d)
PRINT "= "; Codetmp
PRINT
END IF
RETURN
END SUB
SUB Split (X$(), y2$, z$)
y$ = y2$ + z$
l% = LEN(z$)
i% = INSTR(y$, z$)
j% = 1
DO WHILE i%
K% = K% + 1
X$(K%) = MID$(y$, j%, i% - j%)
j% = i% + l%
i% = INSTR(j%, y$, z$)
LOOP
X$(0) = STR$(K%)
END SUB
---------------------
还一个问题
SCREEN 12
FOR a = 100 TO 300
LINE (a, a - 5)-(a * 2, a * 2), 15, B
PAINT (10, 5), 7
NEXT
a$ = INPUT$(1)
CLS
WHILE INKEY$ = ""
FOR i = 10 TO 200
IF INKEY$ = CHR$(13) THEN END
LINE (i + 5, i + 10)-(i * 5, i * 5), 7, BF
FOR b = 0 TO 10000: NEXT
LINE (i + 5, i + 10)-(i * 5, i * 5), 0, BF
NEXT
WEND
怎样解除闪的问题;
10 楼
moz [专家分:37620] 发布于 2006-12-07 20:55:00
想不闪,
1. 少用刷屏CLS之类
2. 尽量画好图像再贴到屏幕上,(这我不在行)
3. 控制好画图的速度.
我来回复