回 帖 发 新 帖 刷新版面

主题:请帮菜鸟检查一下子函数的错误!

以下是运行成功了的正确的代码:
Private Sub Form_Activate()
'如果一个数从左边读和从右边读都是同一个数,则该数叫回文数。
'显示出1000以内所有既是回文数又是素数的自然数
    Dim i As Integer
    Form1.AutoRedraw = True
    For i = 2 To 1000
            If hw(i) Then
                 If ss(i) Then Print i
            End If
    Next i
End Sub
Private Function hw(m As Integer) As Boolean '判断m是否为回文数
    Dim p As Boolean
    p = False
    m = Str(m)
    If Left(m, 1) = Right(m, 1) Then
        p = True
    Else
        p = False
    End If
    hw = p
End Function
Private Function ss(n As Integer) As Boolean '判断n是否为素数
    Dim k As Integer, p As Boolean
    For k = 2 To n - 1
        If n Mod k = 0 Then
              p = False
              Exit For
        Else
                p = True
         End If
    Next k
    ss = p
End Function

问题1:在判断m是否为回文数的子函数hw里,发现如果去掉代码m = Str(m)程序也能运行成功,但left函数和right函数是要求取字符串的子串呀!
问题2:在判断m是否为回文数的子函数hw里,如果去掉代码m = Str(m)这一行并且将代码If Left(m, 1) = Right(m, 1) Then改成If Left(str(m), 1) = Right(str(m), 1) Then则整个程序运行后窗体上将是一片空白----得不到正确结果,这是为什么呢?这种写法有什么不同呢?
还请解答,谢谢!

回复列表 (共8个回复)

沙发

Str()和CStr()的区别。
Str:当一数字转成字符串时,总会在前头保留一空位来表示正负。如果 number 为正,返回的字符串包含一前导空格暗示有一正号
CStr:没有前导空格
VB6在进行默认的类型转换时,应该是用的CStr来转换的。
你在立即窗口中输入 ?len(str(4),len(Cstr(4)就知道Str()和Cstr()结果的差别了。
另外,你的hw()函数中的m=str(m)做的是无用功,甚至是画蛇添足,可以去掉。
你的hw()函数只能判断3位数以下的回文数。

Private Function hw(ByVal m As Long) As Boolean
Dim n   As Long
Dim s1  As String
Dim s2  As String
n = Len(m) / 2
s1 = Left$(m, n)
s2 = Right$(m, n)
s2 = StrReverse(s2)
hw = (s1 = s2)
End Function

板凳

[quote]Str()和CStr()的区别。
Str:当一数字转成字符串时,总会在前头保留一空位来表示正负。如果 number 为正,返回的字符串包含一前导空格暗示有一正号
CStr:没有前导空格
VB6在进行默认的类型转换时,应该是用的CStr来转换的。
你在立即窗口中输入 ?len(str(4),len(Cstr(4)就知道Str()和Cstr()结果的差别了。
另外,你的hw()函数中的m=str(m)做的是无用功,甚至是画蛇添足,可以去掉。
你的hw()函数只能判断3位数以下的回文数。

Private Function hw(ByVal m As Long) As Boolean
Dim n   As Long
Dim s1  As String
Dim s2  As String
n = Len(m) / 2
s1 = Left$(m, n)
s2 = Right$(m, n)
s2 = StrReverse(s2)
hw = (s1 = s2)
End Function
[/quote]
我明白我的hw子函数只能判断3位数以下的回文。
但还是不明白left和right应该给字符串型数据求子串呀,怎么能给数值型的求呢?
还有,m=str(m) 
      if left(m,1)=right(m,1) then

if left(str(m),1)=right(str(m),1) then
有什么不同呢?
如果有前导空格应该出不来正确结果呀!

3 楼

1、[quote]如果有前导空格应该出不来正确结果呀![/quote]
"if left(str(m),1)=right(str(m),1) then "中的str(m)就是有前导空格的,确实没有出正确结果呀!

2、[quote]m=str(m) 
      if left(m,1)=right(m,1) then

if left(str(m),1)=right(str(m),1) then
有什么不同呢?[/quote]
第一种写法中,如前所述,m=str(m)是做的无用功。相当于m=cint(str(m),其结果m仍然是一个Integer.之所以会结果正确,是因为在left(m,1)时,left()需要一个string类型的参数,所以vb6就帮你cstr(m)了。
第二种写法中,left()需要的string类型参数已经由你明确指定Str(m)了,而str(m)带有前导空格,就得不到预想中的结果。
understand ??

4 楼

帮你具体分析一下if left(str(m),1)=right(str(m),1) then

假设m=121,那么str(m)=" 121",left(str(m),1)的结果是一个空格,而right(str(m),1)的结果是“1”,当然不相等

5 楼

[quote]1."if left(str(m),1)=right(str(m),1) then "中的str(m)就是有前导空格的,确实没有出正确结果呀!

2、[quote]m=str(m) 
      if left(m,1)=right(m,1) then

if left(str(m),1)=right(str(m),1) then
有什么不同呢?[/quote]
第一种写法中,如前所述,m=str(m)是做的无用功。相当于m=cint(str(m),其结果m仍然是一个Integer.之所以会结果正确,是因为在left(m,1)时,left()需要一个string类型的参数,所以vb6就帮你cstr(m)了。
understand ??[/quote]
谢谢耐心解答~~~[em2]
在第一种情形中,为什么m=str(m)是在做无用功呢?难道这条代码不能强行将m转换成字符串类型(哪怕是前面加了个空格)吗?
为什么“其结果m仍然是一个Integer”?
还有,“在left(m,1)时,left()需要一个string类型的参数,所以vb6就帮你cstr(m)了”vb6凭什么帮我转换呀?它在什么情况下会自动帮我转换什么情况下必须我人工转换呢?

6 楼

不知你是不是在校学生,老师竟然连这基本知识都不讲,真是的。。。
在第一种情形中,从你的代码分析,m是一个数值型的变量(如果是字串型的变量,你也就不需要转换了),str(m)把m转换成了字符串存放在内存中,这时,如果你把这个字串赋给一个字符串型的变量就是正确的,但是你又把它赋给了m,由于m是数值型变量,所以vb又把这个字串转换为数值再赋给m,这就等于没有转换,不是无用功是什么?
“vb6凭什么帮我转换”就要问盖茨了,这是VB内部的自动转换机制,不需要人工干预的。在什么情况下会自动帮你转换,就要你自己去做试验了,你可以用整型、长整型、单精度、双精度、时间型等等各种数据类型进行试验,这样得到的知识你才能记得牢。

7 楼

[quote]“vb6凭什么帮我转换”就要问盖茨了[/quote]
这句话说得最好了

8 楼

[quote]不知你是不是在校学生,老师竟然连这基本知识都不讲,真是的。。。
[/quote]
汗~~~[em8]

我来回复

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