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 を使用します。私がすべて正しくやっているように見えるので、Googleは助けにはなりませんでした。複数の変数を渡すこと、パラメーターの型を指定すること、型の使用方法を確認しましたが、実際には何も役に立ちませんでした。

みんなありがとう。

4

4 に答える 4

2

関数内でユーザー定義変数を定義または使用することは、QB では違法です。関数が DEF FNname ... END DEF または FUNCTION ... END FUNCTION で宣言されているかどうかは関係ありません。

あなたができることは、ユーザー定義変数のアドレスへのポインターを送信することです。次に、関数/サブルーチンはアドレスを使用してメモリから直接読み取ります。ユーザー定義変数の要素は、定義された順序で正確に保存されます。この例では、最初に a (2 バイト整数) がビッグ エンディアン形式で格納され、次に b の合計 4 バイトが格納されます。

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

これにより、サブにするよりも致命的ではないエラーを簡単に処理できます。

于 2016-07-10T18:39:07.267 に答える
1

しばらく経ちましたが、問題は実際にはUDT(ユーザー定義型、別名「組み込みではない任意の型」)を返すことができないことにあると思います。あなたがする必要があるのは、3 番目の引数を に渡して、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 コードを使用したほぼ正確な翻訳です。私の推論は、通常、QB の a の名前に型サフィックスを追加するか、 (またはQB64 でFUNCTIONオーバーライドされた可能性がある) デフォルトの型を使用することです。UDT では使用できません) たとえば、次の文字列を返します。DEFxxx M-N_DEFINE_DEFINE

'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 で使用される構文と可能な限り互換性を保つことを目的としているため、この点で少し制限されています。QB に基づく別の言語である FreeBASIC には、そのような制限はありません

'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 に答える