1

我试图使用 QB64 V1.2 编译 QB 程序 DIMORDIN.BAS(包含在旧 QB4.5 包中的示例)。

编译并不表示错误,但程序的执行显示出意外……大多数排序类型的执行都会导致分段错误。

调试代码我发现这个结果的原因是语言函数SWAP,有证据表明它不能交换复杂和/或用户定义的类型。这样的行:SWAP MatrOrd(Riga), MatrOrd(Riga + Scarto)给出分段错误。

你有解决办法吗?为什么 QB64 不兼容 QB4.5 的这个特性?

以下代码是给出分段错误的 SUB 的原始代码(不幸的是,我只有意大利语版本)。

我不能在这里发布完整的代码,因为它超过 30,000 个字符。

SUB OrdShell STATIC

    ' Imposta lo scarto per il confronto a met del numero di record in MatrOrd:
    Scarto = RigheMass \ 2

    PRINT
    DO WHILE Scarto > 0 ' Cicla finch Scarto non diventa zero.
        Limite = RigheMass - Scarto
        DO
            Scambi = FALSO ' Presume non vi siano stati scambi
            ' con questo valore di Scarto.

            ' Confronta elementi e scambia quelli non in ordine:
            FOR Riga = 1 TO Limite
                IF MatrOrd(Riga).Lung > MatrOrd(Riga + Scarto).Lung THEN
                    SWAP MatrOrd(Riga), MatrOrd(Riga + Scarto)
                    ScambiaBarre Riga, Riga + Scarto
                    Scambi = Riga
                END IF
            NEXT Riga

            ' Al passaggio successivo ordina solo fino al punto dell'ultimo
            ' scambio:
            Limite = Scambi - Scarto
        LOOP WHILE Scambi

        ' Nessuno scambio al precedente valore di scarto; lo dimezza:
        Scarto = Scarto \ 2
    LOOP
END SUB

为了帮助您理解 SUB,我添加了程序的声明部分:

' Definisce il tipo di dati usato per contenere i dati delle barre:
TYPE TipoOrd
    Lung AS INTEGER ' Lunghezza della barra (l'elemento di
    ' confronto nei vari ordinamenti)
    ValColore AS INTEGER ' Colore della barra
    StringaBarra AS STRING * 43 ' La barra (una stringa di 43 caratteri)
END TYPE

' Dichiara le costanti globali:
CONST FALSO = 0, VERO = NOT FALSO, COLONNASIN = 49
CONST NUMOPZIONI = 11, NUMORDINAMENTI = 6

' Dichiara le variabili globali e alloca loro spazio nella memoria. MatrOrd
' e BackupOrd sono matrici del tipo di dati TipoOrd definito sopra:
DIM SHARED MatrOrd(1 TO 43) AS TipoOrd, BackupOrd(1 TO 43) AS TipoOrd
DIM SHARED LeggendaOpzioni(1 TO NUMOPZIONI) AS STRING * 14
DIM SHARED TempoIniz AS SINGLE
DIM SHARED PrimoPiano, Sfondo, Silenzio, Pausa
DIM SHARED Selezione, RigheMass, RigheIniz, ColoriMass

我编写了以下小代码来演示函数SWAP生成的问题:

$CONSOLE:ONLY
_DEST _CONSOLE

TYPE TipoOrd
    Lung AS INTEGER ' Lunghezza della barra (l'elemento di
    ' confronto nei vari ordinamenti)
    ValColore AS INTEGER ' Colore della barra
    StringaBarra AS STRING * 43 ' La barra (una stringa di 43 caratteri)
END TYPE

DIM a(1 TO 43) AS TipoOrd

a(1).Lung = 2: a(2).Lung = 4
PRINT a(1).Lung, a(2).Lung
SWAP a(1), a(2)
PRINT a(1).Lung, a(2).Lung

END
4

2 回答 2

1

我已经编写了这个 QB64 v1.3a 代码来交换结构并取得了一些成功:

TYPE Struct1
    Element1 AS INTEGER
    Element2 AS INTEGER
END TYPE
DIM SHARED StructA(10) AS Struct1
DIM SHARED StructB(10) AS Struct1
StructA(1).Element1 = -1
StructB(1).Element1 = 1
PRINT "StructA="; StructA(1).Element1
PRINT "StructB="; StructB(1).Element1
PRINT "Swap:"
SWAP StructA(1), StructB(1)
PRINT "StructA="; StructA(1).Element1
PRINT "StructB="; StructB(1).Element1
END
于 2019-11-15T04:57:42.627 回答
1

喝完咖啡后,我解决了编写SWAPT执行用户定义类型变量之间交换的子程序的问题TipoOrd

在我 SWAP用子程序替换函数后SWAPT,程序正确运行。

然而,关于 QB64 e QB4.5 之间不合规的问题仍然存在。

这里修改的函数和SWAPT子程序:

SUB OrdShell STATIC

    ' Imposta lo scarto per il confronto a met del numero di record in MatrOrd:
    Scarto = RigheMass \ 2

    PRINT
    DO WHILE Scarto > 0 ' Cicla finch Scarto non diventa zero.
        Limite = RigheMass - Scarto
        DO
            Scambi = FALSO ' Presume non vi siano stati scambi
            ' con questo valore di Scarto.

            ' Confronta elementi e scambia quelli non in ordine:
            FOR Riga = 1 TO Limite
                IF MatrOrd(Riga).Lung > MatrOrd(Riga + Scarto).Lung THEN
                    REM SWAP MatrOrd(Riga), MatrOrd(Riga + Scarto)                             
                    SWAPT MatrOrd(Riga), MatrOrd(Riga + Scarto)

                    ScambiaBarre Riga, Riga + Scarto
                    Scambi = Riga
                END IF
            NEXT Riga

            ' Al passaggio successivo ordina solo fino al punto dell'ultimo
            ' scambio:
            Limite = Scambi - Scarto
        LOOP WHILE Scambi

        ' Nessuno scambio al precedente valore di scarto; lo dimezza:
        Scarto = Scarto \ 2
    LOOP
END SUB

SUB SWAPT (a AS TipoOrd, b AS TipoOrd)
    SWAP a.Lung, b.Lung
    SWAP a.ValColore, b.ValColore
    SWAP a.StringaBarra, b.StringaBarra
END SUB
于 2019-11-13T15:36:18.517 回答