2

出于怀旧的原因回到了旧的 qbasic 并且之前从未在 qbasic 中使用过类型和函数,因为那时我还很年轻。

TYPE Vector2
    x AS SINGLE
    y AS SINGLE
END TYPE

FUNCTION Vector2Mag (a AS Vector2)
    Vector2Mag = SQR((a.x * a.x) + (a.y * a.y))
END FUNCTION

FUNCTION Vector2Add (a AS Vector2, b AS Vector2)
    DIM r AS Vector2
    r.x = a.x + b.x
    r.y = a.y + b.y
    Vector2Add = r
END FUNCTION

但我明白了

Illegal SUB/FUNCTION parameter on current line

在两个第一个函数行中使用 qb64。谷歌没有帮助,因为看起来我做的一切都是正确的。我检查了传递多个变量,为参数指定类型,如何使用类型,但没有任何帮助。

多谢你们。

4

4 回答 4

2

在 QB 中定义或使用函数内部的用户定义变量是非法的。不管函数是由 DEF FNname ... END DEF 还是 FUNCTION ... END FUNCTION 声明的

您可以做的是发送一个指向用户定义变量地址的指针,然后函数/子使用该地址直接从内存中读取它。用户定义变量的元素完全按照定义的顺序存储。在这个例子中,a(两字节整数)将首先以大端格式存储,然后是 b,总共四个字节。

TYPE xtyp
DIM a AS INTEGER
DIM b AS INTEGER
END TYPE
DIM var AS xtyp
var.a = 5
var.b = 7
DEF SEG = VARSEG(var)
PRINT "The value of var.a and var.b multiplied is"; mpl(VARPTR(var))
END
'-------------------------- End of main program, function begins here    -------
FUNCTION mpl(addr)
factor1 = PEEK(addr) + PEEK(addr + 1) * 256
factor2 = PEEK(addr + 2) + PEEK(addr + 3) * 256
mpl = factor1 * factor2
END FUNCTION

DEF SEG用于设置当前段,并VARSEG()返回数字或用户定义变量的段。 PEEK()用于从某个内存位置读取一个字节,并VARPTR()返回其段中数字或用户定义变量的地址。请注意,上面的代码假设这两个因素都是无符号的。如果它们是有符号的,则将单个字节转换为整数必须略有不同。

于 2016-02-21T07:04:58.000 回答
1

让函数写入共享变量并让它返回 -1 表示成功

TYPE testType
    x AS INTEGER
    y AS INTEGER
END TYPE
DIM SHARED ret AS testType
DIM a AS testType,b as testType
a.x=5
b.x=7
IF add(a,b) THEN a=ret
FUNCTION add(a AS testType, b AS testType)
ret.x=a.x+b.x
ret.y=a.y+b.y
add=-1
END FUNCTION

与将其设置为 SUB 相比,这可以更轻松地处理非致命错误

于 2016-07-10T18:39:07.267 回答
1

已经有一段时间了,但我认为问题实际上是您无法返回 UDT(用户定义的类型,又名“任何非内​​置类型”)。您需要做的是将第三个参数传递给Vector2Add并使其成为SUB. 例如:

SUB Vector2Add (r AS Vector2, a AS Vector2, b AS Vector2)
    r.x = a.x + b.x
    r.y = a.y + b.y
END SUB

SUB除了语法差异之外,这几乎是与等效 C 代码的精确翻译。我的理由是,您通常会FUNCTION在 QB 中的 a 名称中添加类型后缀,否则它将使用其默认类型,该类型可能已被DEFxxx M-N(或_DEFINE在 QB64 中;不,您不能_DEFINE与 UDT 一起使用)覆盖。例如,返回一个字符串:

'Default type for all identifiers beginning with 'S' is STRING.
' Type suffixes, "AS xxxx" clauses and future "DEFxxx" items override the behavior.
DEFSTR S-S

FUNCTION swapFirstLast$ (s)
    swapFirstLast$ = RIGHT$(s, 1) + MID$(s, 2, LEN(s) - 2) + LEFT$(s, 1)
END FUNCTION

QB64 在这方面有点受限,因为它旨在与 QuickBASIC 4.5 使用的语法尽可能兼容。FreeBASIC 是另一种基于 QB 的语言,没有这样的限制

'Notice the "AS Vector2" at the end of this next line and the RETURN statement
' that FB introduced for FUNCTIONs (originally it was used to return from an
' "old-style" subroutine that was invoked via the GOSUB statement).
FUNCTION Vector2Add (a AS Vector2, b AS Vector2) AS Vector2
    DIM r AS Vector2
    r.x = a.x + b.x
    r.y = a.y + b.y
    RETURN r
END FUNCTION

要记住的重要一点是,QB64 基本上仍然是 QB,除了它将编译代码以在现代操作系统(而不是 DOS)上运行。另一方面,FreeBASIC 选择牺牲一些兼容性来创建一种更“现代”的语言,保留 QB 的语法。

于 2016-02-06T22:04:59.527 回答
0

不要尝试将 UDT 返回到函数名称,而是使用全局 UDT:

TYPE Vector2
    x AS SINGLE
    y AS SINGLE
END TYPE

DIM SHARED r AS Vector2

FUNCTION Vector2Mag (a AS Vector2)
Vector2Mag = SQR((a.x * a.x) + (a.y * a.y))
END FUNCTION

FUNCTION Vector2Add (a AS Vector2, b AS Vector2)
r.x = a.x + b.x
r.y = a.y + b.y
'Vector2Add = r
END FUNCTION
于 2016-08-28T02:00:46.523 回答