回 帖 发 新 帖 刷新版面

主题:回MOZ;求助

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个回复)

沙发

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.  你既然知道“不规则表达式时;程序就有错误;”
    那么你就应该想办法怎么检测这样的错误,
    怎样避免这样的错误,怎样处理这样的错误。
    比如说没有左括号该怎办,没有右括号该怎办。
    分出来的字符串不是有效数值该怎办。

板凳


好建议;
'------------------------------
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 楼

QB里的堆栈空间很有限的,
可以用命令扩充堆栈空间,但很危险,也不方便.
在QB里不建议使用过多的递归,建议<20次.
具体次数与你函数(或过程)中使用的变量空间有关.

4 楼


哪怎样解决上面的问题;
总不能PRINT “ERROR”吧;

5 楼

大部份错误是可以在编程阶段中解决的,
而不必要等到出现不明错误的时候来做,
而且你也不一定知道是什么错.

关于反复递归调用的堆栈溢出问题,溢出的只是QB的问题
建议使用更高级的编程工具,可以很好的避免问题.

事必要用QB的话,可以用数组代替,
我曾发过此类贴,很旧了,关键字:"递归","数组"

6 楼


我现在有一个VBDOS;
不知有什么限制;

7 楼


怎样有数组剃归啊;

8 楼

VBDOS也就是VB1.0
都是DOS下的编程工具,
具体堆栈空间我没测试过不太清楚,
估计会有改进。

至于数组怎样替代递归,你可以想像一下,
递归的原理是怎样的?
1. 保存现场,可进可退。
2. 跳进新套,得出结果。
3. 返回旧套,恢复现场。
知道哪些变量需要怎样记录,
哪些变量需要怎样恢复和处理,
因为数量太多,用数组实现就可以了。

缺点,你的脑袋结构需要一点复杂程度,
你需要记得哪个位置怎样用哪个位置怎样恢复。
一般人无法正常理解。

9 楼


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 楼

想不闪,
1. 少用刷屏CLS之类
2. 尽量画好图像再贴到屏幕上,(这我不在行)
3. 控制好画图的速度.

我来回复

您尚未登录,请登录后再回复。点此登录或注册