Discussion:
C to PB help.
(too old to reply)
Anonymous
2007-10-26 06:38:38 UTC
Permalink
Hello,

I'm trying to convert some piece of C code to PB, but have some trouble to
convert C memory manipulation code to its equivalent in PB, which results is
incorrect output; from the PB code.See below.

Hopefully someone could have some advice to share.
Thanks in advance!
--

#COMPILER PBCC 4.04
#COMPILE EXE
#DIM ALL
'------------------------------------------------------------------------------------------
TYPE HeapType
length AS LONG
node AS DWORD PTR
END TYPE
'------------------------------------------------------------------------------------------
FUNCTION fLeft(BYVAL i AS LONG)AS LONG
SHIFT LEFT i,1
i = i + 1
fLeft = i
END FUNCTION
'------------------------------------------------------------------------------------------
SUB hpSwap(BYVAL i AS DWORD PTR,BYVAL j AS DWORD PTR)
LOCAL k AS DWORD
k = j
k= j
j = i
i = k
END SUB
'------------------------------------------------------------------------------------------
SUB Fix_Heap(BYVAL hp AS HeapType PTR,BYVAL i AS LONG)
REGISTER m AS LONG,h AS LONG
m = fLeft(i)
IF m < @hp.length THEN
h = m + 1
IF h < @hp.length AND @***@node[h] > @***@node[m] THEN m = h
IF @***@node[m] > @***@node[i]THEN
hpSwap @hp.node+i,@hp.node+m
Fix_Heap hp,m
END IF
END IF
END SUB
'--------------------------------------------------------------------------------------------
SUB Fix_Heap_Test()
DIM hp AS LOCAL HeapType
LOCAL i AS LONG
DIM ary(9) AS LOCAL LONG
ARRAY ASSIGN ary() = 9,2,10,12,7,5,8,1,3,5
hp.node = VARPTR(ary(1))
hp.length = UBOUND(ary)-1
Fix_heap VARPTR(hp),0
FOR i = 0 TO hp.length
? ***@node[i] 'Output :2,10,12,7,5,8,1,3,5
NEXT 'Should be:12,10,8, 7,5,2,1,3,5 as in the C code.
END SUB
'------------------------------------------------------------------------------------------
FUNCTION PBMAIN () AS LONG

Fix_Heap_Test()
WAITKEY$

END FUNCTION
'---------------------------END OF PB
CODE---------------------------------------

//---------------------------START OF C
CODE---------------------------------------
#include <string.h>
#include <memory.h>
#pragma hdrstop
//------------------------------------------------------------------------------------
typedef struct {
int len;
int node[];
}heap;
//----------------------------------------------------------------------------------------int fLeft(int i){return (i << 1) + 1;} //---------------------------------------------------------------------------------------- void Swap(int *i, int *j) { int k = *j; *j = *i; *i = k;}//---------------------------------------------------------------------------------------- void Fix_heap(heap *hp, int i) { int m = fLeft(i); if (m < hp->len){ int h = m + 1; if (h < hp->len && hp->node[h] > hp->node[m]) m = h; if (hp->node[m] > hp->node[i]) { Swap(hp->node+i, hp->node+m); Fix_heap(hp, m); } } } //--------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { int i; int ary[]={9, 2, 10, 12, 7, 5, 8, 1, 3, 5}; heap *hp = (heap *) malloc(sizeof(int)*10); //9 elem. + len memcpy(hp, ary, sizeof(ary)); Fix_heap(hp, 0); for (i=0; i<hp->len; i++) printf(" %i", hp->node[i]); getch(); return 0; }//---------------------------------------------------------------------------
Anonymous
2007-10-26 06:51:04 UTC
Permalink
The C code looks garbled in my news reader, so I'll post it one more time.
--

//---------------------------START OF C
CODE---------------------------------------
#include <string.h>
#include <memory.h>
#pragma hdrstop
//------------------------------------------------------------------------------------
typedef struct {
int len;
int node[];
}heap;
//----------------------------------------------------------------------------------------int fLeft(int i){return (i << 1) + 1;} //---------------------------------------------------------------------------------------- void Swap(int *i, int *j) { int k = *j; *j = *i; *i = k;}//---------------------------------------------------------------------------------------- void Fix_heap(heap *hp, int i) { int m = fLeft(i); if (m < hp->len){ int h = m + 1; if (h < hp->len && hp->node[h] > hp->node[m]) m = h; if (hp->node[m] > hp->node[i]) { Swap(hp->node+i, hp->node+m); Fix_heap(hp, m); } } } //--------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { int i; int ary[]={9, 2, 10, 12, 7, 5, 8, 1, 3, 5}; heap *hp = (heap *) malloc(sizeof(int)*10); //9 elem. + len memcpy(hp, ary, sizeof(ary)); Fix_heap(hp, 0); for (i=0; i<hp->len; i++) printf(" %i", hp->node[i]); getch(); return 0; }//---------------------------------------------------------------------------"Anonymous" <***@b.cd> skrev i meldingnews:gYfUi.1519$***@newsread1.mlpsca01.us.to.verio.net...> Hello,>> I'm trying to convert some piece of C code to PB, but have some trouble toconvert C memory manipulation code to its equivalent in PB, which results isincorrect output; from the PB code.See below.>> Hopefully someone could have some advice to share.> Thanks in advance!> -->> #COMPILER PBCC 4.04> #COMPILE EXE> #DIM ALL>'------------------------------------------------------------------------------------------> TYPE HeapType> length AS LONG> node AS DWORD PTR> END TYPE>'------------------------------------------------------------------------------------------> FUNCTION fLeft(BYVAL i AS LONG)AS LONG> SHIFT LEFT i,1> i = i + 1> fLeft = i> END FUNCTION>'------------------------------------------------------------------------------------------> SUB hpSwap(BYVAL i AS DWORD PTR,BYVAL j AS DWORD PTR)> LOCAL k AS DWORD> k = j> k= j> j = i> i = k> END SUB>'------------------------------------------------------------------------------------------> SUB Fix_Heap(BYVAL hp AS HeapType PTR,BYVAL i AS LONG)> REGISTER m AS LONG,h AS LONG> m = fLeft(i)> IF m < @hp.length THEN> h = m + 1> IF h < @hp.length AND @***@node[h] > @***@node[m] THEN m = h> IF @***@node[m] > @***@node[i]THEN> hpSwap @hp.node+i,@hp.node+m> Fix_Heap hp,m> END IF> END IF> END SUB>'--------------------------------------------------------------------------------------------> SUB Fix_Heap_Test()> DIM hp AS LOCAL HeapType> LOCAL i AS LONG> DIM ary(9) AS LOCAL LONG> ARRAY ASSIGN ary() = 9,2,10,12,7,5,8,1,3,5> hp.node = VARPTR(ary(1))> hp.length = UBOUND(ary)-1> Fix_heap VARPTR(hp),0> FOR i = 0 TO hp.length> ? ***@node[i] 'Output :2,10,12,7,5,8,1,3,5> NEXT 'Should be:12,10,8, 7,5,2,1,3,5 as in the C code.> END SUB>'------------------------------------------------------------------------------------------> FUNCTION PBMAIN () AS LONG>> Fix_Heap_Test()> WAITKEY$>> END FUNCTION> '---------------------------END OF PBCODE--------------------------------------->> //---------------------------START OF CCODE---------------------------------------> #include <string.h>> #include <memory.h>> #pragma hdrstop>//------------------------------------------------------------------------------------> typedef struct {> int len;> int node[];> }heap;>//----------------------------------------------------------------------------------------int fLeft(int i){return (i << 1) + 1;}//---------------------------------------------------------------------------------------- void Swap(int *i, int *j) { int k = *j; *j = *i; *i =k;}//---------------------------------------------------------------------------------------- void Fix_heap(heap *hp, int i) { int m = fLeft(i);if (m < hp->len){ int h = m + 1; if (h < hp->len && hp->node[h] >hp->node[m]) m = h; if (hp->node[m] > hp->node[i]) {Swap(hp->node+i, hp->node+m); Fix_heap(hp, m); } } }//--------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { int i; int ary[]={9,2, 10, 12, 7, 5, 8, 1, 3, 5}; heap *hp = (heap *) malloc(sizeof(int)*10);//9 elem. + len memcpy(hp, ary, sizeof(ary)); Fix_heap(hp, 0); for(i=0; i<hp->len; i++) printf(" %i", hp->node[i]); getch(); return; }//--------------------------------------------------------------------------->
Judson McClendon
2007-10-26 10:55:14 UTC
Permalink
The C code looks garbled in my news reader...
The C source code is probably from a ?nix system with only a LF character at the end of the line instead of CRLF. PowerBASIC Console
Compiler installs program CRLF in the Samples folder, and it will fix the file. Or search powerbasic.com for the file LF2CRLF.ZIP
which contains such a program.
--
Judson McClendon ***@sunvaley0.com (remove zero)
Sun Valley Systems http://sunvaley.com
"For God so loved the world that He gave His only begotten Son, that
whoever believes in Him should not perish but have everlasting life."
Judson McClendon
2007-10-26 12:30:06 UTC
Permalink
Post by Judson McClendon
The C code looks garbled in my news reader...
The C source code is probably from a ?nix system with only a LF
character at the end of the line instead of CRLF. PowerBASIC Console
Compiler installs program CRLF in the Samples folder, and it will fix the
file. Or search powerbasic.com for the file LF2CRLF.ZIP which contains
such a program.
Actually, this provoked me into writing a better one. It doesn't simply change
'LF' into CRLF, which will screw up the file if it already has CRLF (e.g. you
run it twice on the same file) but 'corrects' CRLF, even if it already has CRLF
in some or all lines, or has CR instead of LF, which I have seen. You can run
this program repeatedly on any correct ASCII CRLF text file and it won't
mess it up. However, if the file has CRLF reversed as LFCR, which I've also
seen, it will change LFCR to double CRLF. For such (rare) files, modify the
code to first change LFCR to LF, or simply remove all CR's first. I don't
know of a good way to certainly recognize such files at runtime. Even if you
scanned for the first CR and checked for an LF before it, you wouldn't know
for certain that it wasn't a ?nix LF file that happened to have a CR, or a CR
format that happened to have a LF, both of which I have seen (it's fairly
common to see CRLF followed by one or more LF's or CR's when the file
is the redirected output of a program). But the following program will work
for LF-only, CR-only, CRLF or mixed formats, changing them to CRLF. It
uses the overall best algorithm for CRLF correction.

'
' **************************************************
' * *
' * FixCRLF.bas *
' * *
' * Convert files to proper CRLF format *
' * *
' * Wildcards and drive/path may be used *
' * *
' * Compile using PB/CC *
' * *
' * Judson D. McClendon *
' * Sun Valley Systems *
' * 4522 Shadow Ridge Pkwy *
' * Pinson, AL 35126-2192 *
' * 205-680-0460 *
' * *
' **************************************************
'
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC"

DECLARE SUB ParseFiles(ParamStr AS STRING, FileTab() AS STRING, FileEnd AS LONG)
DECLARE SUB ExpandWildcard(WildCard AS STRING, FileTab() AS STRING, FileEnd AS LONG)
DECLARE SUB ParseParams(ParamStr AS STRING, ParamTab() AS STRING, ParamEnd AS LONG)

FUNCTION PBMAIN () AS LONG
DIM FileTab(10) AS STRING
DIM FileEnd AS LONG
DIM FilePtr AS LONG
DIM TempParams AS STRING
DIM FileName AS STRING
DIM FileText AS STRING

TempParams = TRIM$(COMMAND$)
IF (TempParams = "/?" OR TempParams = "-?") THEN
STDOUT "FixCRLF: Convert files to proper CRLF format"
STDOUT " Usage: FixCRLF filespec [filespec [filespec ...]]"
STDOUT " Wildcards and drive/path may be used"
EXIT FUNCTION
END IF

ParseFiles(TempParams, FileTab(), FileEnd)

IF (FileEnd = 0) THEN
STDOUT "No files found"
EXIT FUNCTION
END IF

FOR FilePtr = 1 TO FileEnd
FileName = DIR$(FileTab(FilePtr),16)
IF (FileName = "") THEN
STDOUT $DQ & FileTab(FilePtr) & $DQ & " not found"
ITERATE FOR
END IF
IF ((GETATTR(FileTab(FilePtr)) AND 16) <> 0) THEN
STDOUT $DQ & FileTab(FilePtr) & $DQ & " is a folder, not a file"
ITERATE FOR
END IF

' Read entire file into string FileText
TRY
OPEN FileName FOR BINARY ACCESS READ AS #1
GET$ 1, LOF(1), FileText
CLOSE #1
CATCH
STDOUT "** Couldn't read file " & FileName
ITERATE FOR
END TRY

' Change CRLF to LF in case file was already CRLF
REPLACE $CRLF WITH $LF IN FileText

' Change CR to LF in case file uses CR only
REPLACE $CR WITH $LF IN FileText

' Change LF to CRLF
REPLACE $LF WITH $CRLF IN FileText

' Write modified file back to disk
TRY
KILL FileName
OPEN FileName FOR BINARY ACCESS READ WRITE LOCK READ WRITE AS #1
PUT$ 1, FileText
CLOSE #1
CATCH
STDOUT "** Couldn't rewrite file " & FileName
END TRY

NEXT FilePtr
END FUNCTION


'
' ** Parse COMMAND$ into an array of file names, expanding wildcards
'
SUB ParseFiles(ParamStr AS STRING, FileTab() AS STRING, FileEnd AS LONG)
LOCAL FileName AS STRING
DIM ParamTab(10) AS STRING
DIM ParamEnd AS LONG
DIM ParamPtr AS LONG

ParseParams(ParamStr, ParamTab(), ParamEnd)

FOR ParamPtr = 1 TO ParamEnd
FileName = ParamTab(ParamPtr)
IF (INSTR(FileName, ANY "?*") > 0) THEN
ExpandWildcard(FileName, FileTab(), FileEnd)
ITERATE FOR
END IF

' ' Missing files
' IF (DIR$(FileName,16) = "") THEN
' STDERR "** File " & FileName & " not found"
' ITERATE FOR
' END IF

' ' Subdirectories
' IF ((GETATTR(FileName) AND 16) <> 0) THEN
' STDERR "** " & FileName & " is a folder, not a file"
' ITERATE FOR
' END IF

FileEnd = FileEnd + 1
IF (FileEnd > UBOUND(FileTab)) THEN
REDIM PRESERVE FileTab(UBOUND(FileTab) + 10)
END IF
FileTab(FileEnd) = FileName
NEXT
END SUB


'
' ** Expand wildcard into array of file names
'
SUB ExpandWildcard(WildCard AS STRING, FileTab() AS STRING, FileEnd AS LONG)
LOCAL FileName AS STRING
LOCAL FilePath AS STRING
LOCAL OldPath AS STRING
LOCAL NewPath AS STRING
LOCAL NewDrive AS STRING
LOCAL I AS LONG
LOCAL Attr AS LONG

OldPath = CURDIR$ ' Save old path
I = INSTR(-1,Wildcard, ANY ":\/")
IF (I = 0) THEN
FileName = WildCard
ELSE
FilePath = LEFT$(Wildcard,I)
FileName = MID$(Wildcard,I+1)
NewPath = FilePath
IF (MID$(NewPath,2,1) = ":") THEN
NewDrive = LEFT$(NewPath,2)
TRY
CHDRIVE NewDrive
CATCH
STDERR "** Drive " & NewDrive & " in " & Wildcard & " not found"
EXIT SUB
END TRY
NewPath = MID$(NewPath,3)
END IF
IF (LEN(NewPath) > 1) _
AND _
(INSTR(RIGHT$(NewPath,1), ANY "\/") > 0) THEN
NewPath = LEFT$(NewPath, LEN(NewPath) - 1)
END IF
IF (NewPath <> "") THEN
TRY
CHDIR NewPath
CATCH
STDERR "** Path " & NewPath & " in " & Wildcard & " not found"
EXIT SUB
END TRY
END IF
END IF

FileName = DIR$(FileName,7)
DO WHILE (FileName <> "")
Attr = GETATTR(FileName)
IF ((Attr AND 16) = 0) THEN ' If not subdirectory, store it
FileEnd = FileEnd + 1
IF (FileEnd > UBOUND(FileTab)) THEN
REDIM PRESERVE FileTab(UBOUND(FileTab) + 10)
END IF
FileTab(FileEnd) = FilePath & FileName
END IF
FileName = DIR$
LOOP

' If path was changed, change back
IF (NewPath <> "" OR NewDrive <> "") THEN
CHDRIVE LEFT$(OldPath,2)
CHDIR OldPath
END IF
END SUB


'
' ** Parse arguments into an array
'
SUB ParseParams(ParamStr AS STRING, ParamTab() AS STRING, ParamEnd AS LONG)
LOCAL CharPtr AS LONG
LOCAL TempParams AS STRING

CharPtr = 1
ParamEnd = 0
DO UNTIL (CharPtr > LEN(ParamStr))
TempParams = MID$(ParamStr,CharPtr,1)
IF (TempParams = " ") THEN
CharPtr = CharPtr + 1
ITERATE DO
END IF

ParamEnd = ParamEnd + 1
IF (ParamEnd > UBOUND(ParamTab)) THEN
REDIM PRESERVE ParamTab(UBOUND(ParamTab) + 10)
END IF
IF (TempParams = $DQ) THEN
CharPtr = CharPtr + 1
DO UNTIL (CharPtr > LEN(ParamStr))
TempParams = MID$(ParamStr,CharPtr,1)
IF (TempParams = $DQ) THEN
EXIT DO
ELSE
ParamTab(ParamEnd) = ParamTab(ParamEnd) + TempParams
END IF
CharPtr = CharPtr + 1
LOOP
CharPtr = CharPtr + 1
ELSE
DO UNTIL (CharPtr > LEN(ParamStr))
TempParams = MID$(ParamStr,CharPtr,1)
IF (TempParams = " ") THEN
EXIT DO
END IF
ParamTab(ParamEnd) = ParamTab(ParamEnd) + TempParams
CharPtr = CharPtr + 1
LOOP
END IF
LOOP
END SUB
--
Judson McClendon ***@sunvaley0.com (remove zero)
Sun Valley Systems http://sunvaley.com
"For God so loved the world that He gave His only begotten Son, that
whoever believes in Him should not perish but have everlasting life."
Anonymous
2007-10-26 12:58:23 UTC
Permalink
Done so!
--

//---------------------------START OF C
CODE---------------------------------------

#include <string.h>

#include <memory.h>

#pragma hdrstop

//------------------------------------------------------------------------------------

typedef struct {

int len;

int node[];

}heap;

//----------------------------------------------------------------------------------------int fLeft(int i){return (i << 1) + 1;} //---------------------------------------------------------------------------------------- void Swap(int *i, int *j) { int k = *j; *j = *i; *i = k;}//---------------------------------------------------------------------------------------- void Fix_heap(heap *hp, int i) { int m = fLeft(i); if (m < hp->len){ int h = m + 1; if (h < hp->len && hp->node[h] > hp->node[m]) m = h; if (hp->node[m] > hp->node[i]) { Swap(hp->node+i, hp->node+m); Fix_heap(hp, m); } } } //--------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { int i; int ary[]={9, 2, 10, 12, 7, 5, 8, 1, 3, 5}; heap *hp = (heap *) malloc(sizeof(int)*10); //9 elem. + len memcpy(hp, ary, sizeof(ary)); Fix_heap(hp, 0); for (i=0; i<hp->len; i++) printf(" %i", hp->node[i]); getch(); return 0; }//---------------------------------------------------------------------------"Judson McClendon" <***@sunvaley0.com> skrev i meldingnews:4IjUi.7265$***@bignews9.bellsouth.net...> "Anonymous" <***@b.cd> wrote:>> The C code looks garbled in my news reader...>> The C source code is probably from a ?nix system with only a LF characterat the end of the line instead of CRLF. PowerBASIC Console Compiler installsprogram CRLF in the Samples folder, and it will fix the file. Or searchpowerbasic.com for the file LF2CRLF.ZIP which contains such a program.> --> Judson McClendon ***@sunvaley0.com (remove zero)> Sun Valley Systems http://sunvaley.com> "For God so loved the world that He gave His only begotten Son, that> whoever believes in Him should not perish but have everlasting life.">
Anonymous
2007-10-26 13:11:03 UTC
Permalink
One more time. This time I loaded the file in UltraEdit and saved it in
ANSI/ASCII code DOS format.
--

//---------------------------START OF C
CODE---------------------------------------

#include <string.h>
#include <memory.h>
#pragma hdrstop

//------------------------------------------------------------------------------------

typedef struct {
int len;
int node[];
}heap;

//----------------------------------------------------------------------------------------

int fLeft(int i){return (i << 1) + 1;}

//----------------------------------------------------------------------------------------

void Swap(int *i, int *j) {

int k = *j;
*j = *i;
*i = k;
}

//----------------------------------------------------------------------------------------
void Fix_heap(heap *hp, int i) {

int m = fLeft(i);
if (m < hp->len){
int h = m + 1;
if (h < hp->len && hp->node[h] > hp->node[m]) m = h;
if (hp->node[m] > hp->node[i]) {
Swap(hp->node+i, hp->node+m);
Fix_heap(hp, m);
}
}
}
//---------------------------------------------------------------------------------------

int main(int argc, char *argv[]) {
int i;
int ary[]={9, 2, 10, 12, 7, 5, 8, 1, 3, 5};
heap *hp = (heap *) malloc(sizeof(int)*10); //9 elem. + len
memcpy(hp, ary, sizeof(ary));
Fix_heap(hp, 0);
for (i=0; i<hp->len; i++) printf(" %i", hp->node[i]);
getch();
return 0;
}
//---------------------------------------------------------------------------
Post by Judson McClendon
The C code looks garbled in my news reader...
The C source code is probably from a ?nix system with only a LF character
at the end of the line instead of CRLF. PowerBASIC Console Compiler
installs program CRLF in the Samples folder, and it will fix the file. Or
search powerbasic.com for the file LF2CRLF.ZIP which contains such a
program.
--
Sun Valley Systems http://sunvaley.com
"For God so loved the world that He gave His only begotten Son, that
whoever believes in Him should not perish but have everlasting life."
Michael Mattias
2007-10-26 13:33:24 UTC
Permalink
Post by Anonymous
One more time. This time I loaded the file in UltraEdit and saved it in
ANSI/ASCII code DOS format.
void Swap(int *i, int *j) {
....
//----------------------------------------------------------------------------------------
void Fix_heap(heap *hp, int i) {
int main(int argc, char *argv[]) {
int i;
Looks like a quicksort, or at least some kind of sort.

Which begs the question: Wouldn't ARRAY SORT be a hell of a lot easier?
--
Michael C. Mattias
Tal Systems Inc.
Racine WI
***@talsystems.com
Anonymous
2007-10-26 13:58:19 UTC
Permalink
How can ARRAY SORT sort from 2,10,12,7,5,8,1,3,5 to12,10,8, 7,5,2,1,3,5? As
you can see the table isn't sorted; neither in ascending nor descending
order. At least not the whole part of it.It would be very hard for ARRAY
SORT to find which item in the table should be moved; in accordance with how
a heap data structure should be organized.

Secondly I'm currently studying Algorithms and Datastructures at the moment,
and this code is about the heap structures, as you probably spotted.
PB is just a tool in this study, not the target. I don't think ARRAY SORT
would be just as efficient here.Direct memory manipulation, as in the C
code, would be much more preferable.
--
Post by Michael Mattias
Post by Anonymous
One more time. This time I loaded the file in UltraEdit and saved it in
ANSI/ASCII code DOS format.
void Swap(int *i, int *j) {
....
//----------------------------------------------------------------------------------------
void Fix_heap(heap *hp, int i) {
int main(int argc, char *argv[]) {
int i;
Looks like a quicksort, or at least some kind of sort.
Which begs the question: Wouldn't ARRAY SORT be a hell of a lot easier?
--
Michael C. Mattias
Tal Systems Inc.
Racine WI
Michael Mattias
2007-10-26 14:31:46 UTC
Permalink
Post by Anonymous
How can ARRAY SORT sort from 2,10,12,7,5,8,1,3,5 to12,10,8, 7,5,2,1,3,5?
As you can see the table isn't sorted; neither in ascending nor descending
order. At least not the whole part of it.It would be very hard for ARRAY
SORT to find which item in the table should be moved; in accordance with
how a heap data structure should be organized.
Secondly I'm currently studying Algorithms and Datastructures at the
moment, and this code is about the heap structures, as you probably
spotted.
PB is just a tool in this study, not the target.
Well, it looked like some kind of sort. (I am not a C programmer).
Post by Anonymous
I don't think ARRAY SORT would be just as efficient here.Direct memory
manipulation, as in the C code, would be much more preferable.
--
You don't think ARRAY SORT would be as efficient as direct memory
manipulation? Um, what do you think the compiler does when your source code
reads "ARRAY SORT ..??" (Hint: the initials are "direct memory
manipulation").

Then again, using ARRAY SORT doesn't really teach you much about structures
and memory management. Of course, that's why people actually purchase
licenses for high-level language products, so they don't have to do all that
dirty work themselves.

MCM
Judson McClendon
2007-10-26 20:39:29 UTC
Permalink
I don't think ARRAY SORT would be just as efficient here.Direct memory manipulation, as in the C code, would be much more
preferable.
You don't think ARRAY SORT would be as efficient as direct memory manipulation? Um, what do you think the compiler does when your
source code reads "ARRAY SORT ..??" (Hint: the initials are "direct memory manipulation").
Then again, using ARRAY SORT doesn't really teach you much about structures and memory management. Of course, that's why people
actually purchase licenses for high-level language products, so they don't have to do all that dirty work themselves.
He is studying sorting algorithms (algorithms & data structures), so using
array sort wouldn't help with that. :-)
--
Judson McClendon ***@sunvaley0.com (remove zero)
Sun Valley Systems http://sunvaley.com
"For God so loved the world that He gave His only begotten Son, that
whoever believes in Him should not perish but have everlasting life."
Judson McClendon
2007-10-26 14:43:04 UTC
Permalink
How can ARRAY SORT sort from 2,10,12,7,5,8,1,3,5 to12,10,8, 7,5,2,1,3,5? As you can see the table isn't sorted; neither in
ascending nor descending order. At least not the whole part of it.It would be very hard for ARRAY SORT to find which item in the
table should be moved; in accordance with how a heap data structure should be organized.
Secondly I'm currently studying Algorithms and Datastructures at the moment, and this code is about the heap structures, as you
probably spotted.
PB is just a tool in this study, not the target. I don't think ARRAY SORT would be just as efficient here.Direct memory
manipulation, as in the C code, would be much more preferable.
My favorite books on algorithms & data structures are "Algorithms" by Robert
Sedgewick and "Algorithms + Data Structures = Programs" by Niklaus Wirth.
But "Practical Algorithms for Programmers" by Binstock & Rex and
"Algorithms in C," also by Sedgewick are also very good.

The following is a sample program that installs with QuickBASIC 4.5, and there
is no copyright notice, so I'm posting it. It demonstrates several sort algorithms,
including Heap Sort, and runs under QBASIC. I'm not sure how good the
implementation of the algorithms is, because I have a Shell Sort algorithm that's
faster than this one. But it should fairly easy to convert the functional stuff to
PowerBASIC. Surely easier than C. :-)
--
Judson McClendon ***@sunvaley0.com (remove zero)
Sun Valley Systems http://sunvaley.com
"For God so loved the world that He gave His only begotten Son, that
whoever believes in Him should not perish but have everlasting life."

' SORTDEMO
' This program graphically demonstrates six common sorting algorithms. It
' prints 25 or 43 horizontal bars, all of different lengths and all in random
' order, then sorts the bars from smallest to longest.
'
' The program also uses SOUND statements to generate different pitches,
' depending on the location of the bar being printed. Note that the SOUND
' statements delay the speed of each sorting algorithm so you can follow
' the progress of the sort. Therefore, the times shown are for comparison
' only. They are not an accurate measure of sort speed.
'
' If you use these sorting routines in your own programs, you may notice
' a difference in their relative speeds (for example, the exchange
' sort may be faster than the shell sort) depending on the number of
' elements to be sorted and how "scrambled" they are to begin with.

DEFINT A-Z ' Default type integer.

' Declare FUNCTION and SUB procedures, and the number and type of arguments:
DECLARE FUNCTION RandInt% (lower, Upper)

DECLARE SUB BoxInit ()
DECLARE SUB BubbleSort ()
DECLARE SUB CheckScreen ()
DECLARE SUB DrawFrame (TopSide, BottomSide, LeftSide, RightSide)
DECLARE SUB ElapsedTime (CurrentRow)
DECLARE SUB ExchangeSort ()
DECLARE SUB HeapSort ()
DECLARE SUB Initialize ()
DECLARE SUB InsertionSort ()
DECLARE SUB PercolateDown (MaxLevel)
DECLARE SUB PercolateUp (MaxLevel)
DECLARE SUB PrintOneBar (Row)
DECLARE SUB QuickSort (Low, High)
DECLARE SUB Reinitialize ()
DECLARE SUB ShellSort ()
DECLARE SUB SortMenu ()
DECLARE SUB SwapBars (Row1, Row2)
DECLARE SUB ToggleSound (Row, Column)

' Define the data type used to hold the information for each colored bar:
TYPE SortType
Length AS INTEGER ' Bar length (the element compared
' in the different sorts)
ColorVal AS INTEGER ' Bar color
BarString AS STRING * 43 ' The bar (a string of 43 characters)
END TYPE

' Declare global constants:
CONST FALSE = 0, TRUE = NOT FALSE, LEFTCOLUMN = 49
CONST NUMOPTIONS = 11, NUMSORTS = 6

' Declare global variables, and allocate storage space for them. SortArray
' and SortBackup are both arrays of the data type SortType defined above:
DIM SHARED SortArray(1 TO 43) AS SortType, SortBackup(1 TO 43) AS SortType
DIM SHARED OptionTitle(1 TO NUMOPTIONS) AS STRING * 12
DIM SHARED StartTime AS SINGLE
DIM SHARED Foreground, Background, NoSound, Pause
DIM SHARED Selection, MaxRow, InitRow, MaxColors

' Data statements for the different options printed in the sort menu:
DATA Insertion, Bubble, Heap, Exchange, Shell, Quick,
DATA Toggle Sound, , < (Slower), > (Faster)

' Begin logic of module-level code:

Initialize ' Initialize data values.
SortMenu ' Print sort menu.
WIDTH 80, InitRow ' Restore original number of rows.
COLOR 7, 0 ' Restore default color
CLS
END

' GetRow, MonoTrap, and RowTrap are error-handling routines invoked by
' the CheckScreen SUB procedure. GetRow determines whether the program
' started with 25, 43, or 50 lines. MonoTrap determines the current
' video adapter is monochrome. RowTrap sets the maximum possible
' number of rows (43 or 25).
'
GetRow:
IF InitRow = 50 THEN
InitRow = 43
RESUME
ELSE
InitRow = 25
RESUME NEXT
END IF

MonoTrap:
MaxColors = 2
RESUME NEXT

RowTrap:
MaxRow = 25
RESUME

' BoxInit
' Calls the DrawFrame procedure to draw the frame around the sort menu,
' then prints the different options stored in the OptionTitle array.
'
SUB BoxInit STATIC
DrawFrame 1, 22, LEFTCOLUMN - 3, 78

LOCATE 3, LEFTCOLUMN + 2: PRINT "QUICKBASIC SORTING DEMO";
LOCATE 5
FOR I = 1 TO NUMOPTIONS - 1
LOCATE , LEFTCOLUMN: PRINT OptionTitle(I)
NEXT I

' Don't print the last option (> Faster) if the length of the Pause
' is down to 1 clock tick:
IF Pause > 1 THEN LOCATE , LEFTCOLUMN: PRINT OptionTitle(NUMOPTIONS);

' Toggle sound on or off, then print the current value for NoSound:
NoSound = NOT NoSound
ToggleSound 12, LEFTCOLUMN + 12

LOCATE NUMOPTIONS + 6, LEFTCOLUMN
PRINT "Type first character of"
LOCATE , LEFTCOLUMN
PRINT "choice ( I B H E S Q T < > )"
LOCATE , LEFTCOLUMN
PRINT "or ESC key to end program: ";
END SUB

' BubbleSort
' The BubbleSort algorithm cycles through SortArray, comparing adjacent
' elements and swapping pairs that are out of order. It continues to
' do this until no pairs are swapped.
'
SUB BubbleSort STATIC
Limit = MaxRow
DO
Switch = FALSE
FOR Row = 1 TO (Limit - 1)

' Two adjacent elements are out of order, so swap their values
' and redraw those two bars:
IF SortArray(Row).Length > SortArray(Row + 1).Length THEN
SWAP SortArray(Row), SortArray(Row + 1)
SwapBars Row, Row + 1
Switch = Row
END IF
NEXT Row

' Sort on next pass only to where the last switch was made:
Limit = Switch
LOOP WHILE Switch

END SUB

' CheckScreen
' Checks for type of monitor (VGA, EGA, CGA, or monochrome) and
' starting number of screen lines (50, 43, or 25).
'
SUB CheckScreen STATIC

' Try locating to the 50th row; if that fails, try the 43rd. Finally,
' if that fails, the user was using 25-line mode:
InitRow = 50
ON ERROR GOTO GetRow
LOCATE InitRow, 1

' Try a SCREEN 1 statement to see if the current adapter has color
' graphics; if that causes an error, reset MaxColors to 2:
MaxColors = 15
ON ERROR GOTO MonoTrap
SCREEN 1
SCREEN 0

' See if 43-line mode is accepted; if not, run this program in 25-line
' mode:
MaxRow = 43
ON ERROR GOTO RowTrap
WIDTH 80, MaxRow
ON ERROR GOTO 0 ' Turn off error trapping.
END SUB

' DrawFrame
' Draws a rectangular frame using the high-order ASCII characters É (201) ,
' » (187) , È (200) , Œ (188) , º (186) , and Í (205). The parameters
' TopSide, BottomSide, LeftSide, and RightSide are the row and column
' arguments for the upper-left and lower-right corners of the frame.
'
SUB DrawFrame (TopSide, BottomSide, LeftSide, RightSide) STATIC
CONST ULEFT = 201, URIGHT = 187, LLEFT = 200, LRIGHT = 188
CONST VERTICAL = 186, HORIZONTAL = 205

FrameWidth = RightSide - LeftSide - 1
LOCATE TopSide, LeftSide
PRINT CHR$(ULEFT); STRING$(FrameWidth, HORIZONTAL); CHR$(URIGHT);
FOR Row = TopSide + 1 TO BottomSide - 1
LOCATE Row, LeftSide
PRINT CHR$(VERTICAL); SPC(FrameWidth); CHR$(VERTICAL);
NEXT Row
LOCATE BottomSide, LeftSide
PRINT CHR$(LLEFT); STRING$(FrameWidth, HORIZONTAL); CHR$(LRIGHT);
END SUB

' ElapsedTime
' Prints seconds elapsed since the given sorting routine started.
' Note that this time includes both the time it takes to redraw the
' bars plus the pause while the SOUND statement plays a note, and
' thus is not an accurate indication of sorting speed.
'
SUB ElapsedTime (CurrentRow) STATIC
CONST FORMAT = " &###.### seconds "

' Print current selection and number of seconds elapsed in
' reverse video:
COLOR Foreground, Background
LOCATE Selection + 4, LEFTCOLUMN - 2
PRINT USING FORMAT; OptionTitle(Selection); TIMER - StartTime;

IF NoSound THEN
SOUND 30000, Pause ' Sound off, so just pause.
ELSE
SOUND 60 * CurrentRow, Pause ' Sound on, so play a note while
END IF ' pausing.

COLOR MaxColors, 0 ' Restore regular foreground and
' background colors.
END SUB

' ExchangeSort
' The ExchangeSort compares each element in SortArray - starting with
' the first element - with every following element. If any of the
' following elements is smaller than the current element, it is exchanged
' with the current element and the process is repeated for the next
' element in SortArray.
'
SUB ExchangeSort STATIC
FOR Row = 1 TO MaxRow
SmallestRow = Row
FOR J = Row + 1 TO MaxRow
IF SortArray(J).Length < SortArray(SmallestRow).Length THEN
SmallestRow = J
ElapsedTime J
END IF
NEXT J

' Found a row shorter than the current row, so swap those
' two array elements:
IF SmallestRow > Row THEN
SWAP SortArray(Row), SortArray(SmallestRow)
SwapBars Row, SmallestRow
END IF
NEXT Row
END SUB

' HeapSort
' The HeapSort procedure works by calling two other procedures - PercolateUp
' and PercolateDown. PercolateUp turns SortArray into a "heap," which has
' the properties outlined in the diagram below:
'
' SortArray(1)
' / \
' SortArray(2) SortArray(3)
' / \ / \
' SortArray(4) SortArray(5) SortArray(6) SortArray(7)
' / \ / \ / \ / \
' ... ... ... ... ... ... ... ...
'
' where each "parent node" is greater than each of its "child nodes"; for
' example, SortArray(1) is greater than SortArray(2) or SortArray(3),
' SortArray(3) is greater than SortArray(6) or SortArray(7), and so forth.
'
' Therefore, once the first FOR...NEXT loop in HeapSort is finished, the
' largest element is in SortArray(1).
'
' The second FOR...NEXT loop in HeapSort swaps the element in SortArray(1)
' with the element in MaxRow, rebuilds the heap (with PercolateDown) for
' MaxRow - 1, then swaps the element in SortArray(1) with the element in
' MaxRow - 1, rebuilds the heap for MaxRow - 2, and continues in this way
' until the array is sorted.
'
SUB HeapSort STATIC
FOR I = 2 TO MaxRow
PercolateUp I
NEXT I

FOR I = MaxRow TO 2 STEP -1
SWAP SortArray(1), SortArray(I)
SwapBars 1, I
PercolateDown I - 1
NEXT I
END SUB

' Initialize
' Initializes the SortBackup and OptionTitle arrays. It also calls the
' CheckScreen, BoxInit, and RandInt% procedures.
'
SUB Initialize STATIC
DIM TempArray(1 TO 43)

CheckScreen ' Check for monochrome or EGA and set
' maximum number of text lines.
FOR I = 1 TO MaxRow
TempArray(I) = I
NEXT I

MaxIndex = MaxRow

RANDOMIZE TIMER ' Seed the random-number generator.
FOR I = 1 TO MaxRow

' Call RandInt% to find a random element in TempArray between 1
' and MaxIndex, then assign the value in that element to BarLength:
Index = RandInt%(1, MaxIndex)
BarLength = TempArray(Index)

' Overwrite the value in TempArray(Index) with the value in
' TempArray(MaxIndex) so the value in TempArray(Index) is
' chosen only once:
TempArray(Index) = TempArray(MaxIndex)

' Decrease the value of MaxIndex so that TempArray(MaxIndex) can't
' be chosen on the next pass through the loop:
MaxIndex = MaxIndex - 1

' Assign the BarLength value to the .Length element, then store
' a string of BarLength block characters (ASCII 223: ß) in the
' .BarString element:
SortBackup(I).Length = BarLength
SortBackup(I).BarString = STRING$(BarLength, 223)

' Store the appropriate color value in the .ColorVal element:
IF MaxColors > 2 THEN
SortBackup(I).ColorVal = (BarLength MOD MaxColors) + 1
ELSE
SortBackup(I).ColorVal = MaxColors
END IF
NEXT I

FOR I = 1 TO NUMOPTIONS ' Read SORT DEMO menu options and store
READ OptionTitle(I) ' them in the OptionTitle array.
NEXT I

CLS
Reinitialize ' Assign values in SortBackup to SortArray and draw
' unsorted bars on the screen.
NoSound = FALSE
Pause = 2 ' Initialize Pause to 2 clock ticks (@ 1/9 second).
BoxInit ' Draw frame for the sort menu and print options.

END SUB

' InsertionSort
' The InsertionSort procedure compares the length of each successive
' element in SortArray with the lengths of all the preceding elements.
' When the procedure finds the appropriate place for the new element, it
' inserts the element in its new place, and moves all the other elements
' down one place.
'
SUB InsertionSort STATIC
DIM TempVal AS SortType
FOR Row = 2 TO MaxRow
TempVal = SortArray(Row)
TempLength = TempVal.Length
FOR J = Row TO 2 STEP -1

' As long as the length of the J-1st element is greater than the
' length of the original element in SortArray(Row), keep shifting
' the array elements down:
IF SortArray(J - 1).Length > TempLength THEN
SortArray(J) = SortArray(J - 1)
PrintOneBar J ' Print the new bar.
ElapsedTime J ' Print the elapsed time.

' Otherwise, exit the FOR...NEXT loop:
ELSE
EXIT FOR
END IF
NEXT J

' Insert the original value of SortArray(Row) in SortArray(J):
SortArray(J) = TempVal
PrintOneBar J
ElapsedTime J
NEXT Row
END SUB

' PercolateDown
' The PercolateDown procedure restores the elements of SortArray from 1 to
' MaxLevel to a "heap" (see the diagram with the HeapSort procedure).
'
SUB PercolateDown (MaxLevel) STATIC
I = 1

' Move the value in SortArray(1) down the heap until it has
' reached its proper node (that is, until it is less than its parent
' node or until it has reached MaxLevel, the bottom of the current heap):
DO
Child = 2 * I ' Get the subscript for the child node.

' Reached the bottom of the heap, so exit this procedure:
IF Child > MaxLevel THEN EXIT DO

' If there are two child nodes, find out which one is bigger:
IF Child + 1 <= MaxLevel THEN
IF SortArray(Child + 1).Length > SortArray(Child).Length THEN
Child = Child + 1
END IF
END IF

' Move the value down if it is still not bigger than either one of
' its children:
IF SortArray(I).Length < SortArray(Child).Length THEN
SWAP SortArray(I), SortArray(Child)
SwapBars I, Child
I = Child

' Otherwise, SortArray has been restored to a heap from 1 to MaxLevel,
' so exit:
ELSE
EXIT DO
END IF
LOOP
END SUB

' PercolateUp
' The PercolateUp procedure converts the elements from 1 to MaxLevel in
' SortArray into a "heap" (see the diagram with the HeapSort procedure).
'
SUB PercolateUp (MaxLevel) STATIC
I = MaxLevel

' Move the value in SortArray(MaxLevel) up the heap until it has
' reached its proper node (that is, until it is greater than either
' of its child nodes, or until it has reached 1, the top of the heap):
DO UNTIL I = 1
Parent = I \ 2 ' Get the subscript for the parent node.

' The value at the current node is still bigger than the value at
' its parent node, so swap these two array elements:
IF SortArray(I).Length > SortArray(Parent).Length THEN
SWAP SortArray(Parent), SortArray(I)
SwapBars Parent, I
I = Parent

' Otherwise, the element has reached its proper place in the heap,
' so exit this procedure:
ELSE
EXIT DO
END IF
LOOP
END SUB

' PrintOneBar
' Prints SortArray(Row).BarString at the row indicated by the Row
' parameter, using the color in SortArray(Row).ColorVal.
'
SUB PrintOneBar (Row) STATIC
LOCATE Row, 1
COLOR SortArray(Row).ColorVal
PRINT SortArray(Row).BarString;
END SUB

' QuickSort
' QuickSort works by picking a random "pivot" element in SortArray, then
' moving every element that is bigger to one side of the pivot, and every
' element that is smaller to the other side. QuickSort is then called
' recursively with the two subdivisions created by the pivot. Once the
' number of elements in a subdivision reaches two, the recursive calls end
' and the array is sorted.
'
SUB QuickSort (Low, High)
IF Low < High THEN

' Only two elements in this subdivision; swap them if they are out of
' order, then end recursive calls:
IF High - Low = 1 THEN
IF SortArray(Low).Length > SortArray(High).Length THEN
SWAP SortArray(Low), SortArray(High)
SwapBars Low, High
END IF
ELSE

' Pick a pivot element at random, then move it to the end:
RandIndex = RandInt%(Low, High)
SWAP SortArray(High), SortArray(RandIndex)
SwapBars High, RandIndex
Partition = SortArray(High).Length
DO

' Move in from both sides towards the pivot element:
I = Low: J = High
DO WHILE (I < J) AND (SortArray(I).Length <= Partition)
I = I + 1
LOOP
DO WHILE (J > I) AND (SortArray(J).Length >= Partition)
J = J - 1
LOOP

' If we haven't reached the pivot element, it means that two
' elements on either side are out of order, so swap them:
IF I < J THEN
SWAP SortArray(I), SortArray(J)
SwapBars I, J
END IF
LOOP WHILE I < J

' Move the pivot element back to its proper place in the array:
SWAP SortArray(I), SortArray(High)
SwapBars I, High

' Recursively call the QuickSort procedure (pass the smaller
' subdivision first to use less stack space):
IF (I - Low) < (High - I) THEN
QuickSort Low, I - 1
QuickSort I + 1, High
ELSE
QuickSort I + 1, High
QuickSort Low, I - 1
END IF
END IF
END IF
END SUB

' RandInt%
' Returns a random integer greater than or equal to the Lower parameter
' and less than or equal to the Upper parameter.
'
FUNCTION RandInt% (lower, Upper) STATIC
RandInt% = INT(RND * (Upper - lower + 1)) + lower
END FUNCTION

' Reinitialize
' Restores the array SortArray to its original unsorted state, then
' prints the unsorted color bars.
'
SUB Reinitialize STATIC
FOR I = 1 TO MaxRow
SortArray(I) = SortBackup(I)
NEXT I

FOR I = 1 TO MaxRow
LOCATE I, 1
COLOR SortArray(I).ColorVal
PRINT SortArray(I).BarString;
NEXT I

COLOR MaxColors, 0
END SUB

' ShellSort
' The ShellSort procedure is similar to the BubbleSort procedure. However,
' ShellSort begins by comparing elements that are far apart (separated by
' the value of the Offset variable, which is initially half the distance
' between the first and last element), then comparing elements that are
' closer together (when Offset is one, the last iteration of this procedure
' is merely a bubble sort).
'
SUB ShellSort STATIC

' Set comparison offset to half the number of records in SortArray:
Offset = MaxRow \ 2

DO WHILE Offset > 0 ' Loop until offset gets to zero.
Limit = MaxRow - Offset
DO
Switch = FALSE ' Assume no switches at this offset.

' Compare elements and switch ones out of order:
FOR Row = 1 TO Limit
IF SortArray(Row).Length > SortArray(Row + Offset).Length THEN
SWAP SortArray(Row), SortArray(Row + Offset)
SwapBars Row, Row + Offset
Switch = Row
END IF
NEXT Row

' Sort on next pass only to where last switch was made:
Limit = Switch - Offset
LOOP WHILE Switch

' No switches at last offset, try one half as big:
Offset = Offset \ 2
LOOP
END SUB

' SortMenu
' The SortMenu procedure first calls the Reinitialize procedure to make
' sure the SortArray is in its unsorted form, then prompts the user to
' make one of the following choices:
'
' * One of the sorting algorithms
' * Toggle sound on or off
' * Increase or decrease speed
' * End the program
'
SUB SortMenu STATIC
Escape$ = CHR$(27)

' Create a string consisting of all legal choices:
Option$ = "IBHESQ><T" + Escape$

DO

' Make the cursor visible:
LOCATE NUMOPTIONS + 8, LEFTCOLUMN + 27, 1

Choice$ = UCASE$(INPUT$(1)) ' Get the user's choice and see
Selection = INSTR(Option$, Choice$) ' if it's one of the menu options.

' User chose one of the sorting procedures:
IF (Selection >= 1) AND (Selection <= NUMSORTS) THEN
Reinitialize ' Rescramble the bars.
LOCATE , , 0 ' Make the cursor invisible.
Foreground = 0 ' Set reverse-video values.
Background = 7
StartTime = TIMER ' Record the starting time.
END IF

' Branch to the appropriate procedure depending on the key typed:
SELECT CASE Choice$
CASE "I"
InsertionSort
CASE "B"
BubbleSort
CASE "H"
HeapSort
CASE "E"
ExchangeSort
CASE "S"
ShellSort
CASE "Q"
QuickSort 1, MaxRow
CASE ">"

' Decrease pause length to speed up sorting time, then redraw
' the menu to clear any timing results (since they won't compare
' with future results):
Pause = (2 * Pause) / 3
BoxInit

CASE "<"

' Increase pause length to slow down sorting time, then redraw
' the menu to clear any timing results (since they won't compare
' with future results):
Pause = (3 * Pause) / 2
BoxInit

CASE "T"
ToggleSound 12, LEFTCOLUMN + 12

CASE Escape$

' User pressed ESC, so exit this procedure and return to
' module level:
EXIT DO

CASE ELSE

' Invalid key
END SELECT

IF (Selection >= 1) AND (Selection <= NUMSORTS) THEN
Foreground = MaxColors ' Turn off reverse video.
Background = 0
ElapsedTime 0 ' Print final time.
END IF

LOOP

END SUB

' SwapBars
' Calls PrintOneBar twice to switch the two bars in Row1 and Row2,
' then calls the ElapsedTime procedure.
'
SUB SwapBars (Row1, Row2) STATIC
PrintOneBar Row1
PrintOneBar Row2
ElapsedTime Row1
END SUB

' ToggleSound
' Reverses the current value for NoSound, then prints that value next
' to the "Toggle Sound" option on the sort menu.
'
SUB ToggleSound (Row, Column) STATIC
NoSound = NOT NoSound
LOCATE Row, Column
IF NoSound THEN
PRINT ": OFF";
ELSE
PRINT ": ON ";
END IF
END SUB
Olav Bergesen
2007-11-12 18:57:05 UTC
Permalink
Change the line hpSwap @hp.node+i,@hp.node+m to hpSwap
@hp.node+(i*4),@hp.node+(m*4). It looks like that Powerbasic does not
understand how to do pointer arithmetic in the way C does it.

And change the lines in hpSwap to:
k = @j
@j = @i
@i = k
--

Olaf B
Post by Anonymous
Hello,
I'm trying to convert some piece of C code to PB, but have some trouble to
convert C memory manipulation code to its equivalent in PB, which results
is incorrect output; from the PB code.See below.
Hopefully someone could have some advice to share.
Thanks in advance!
--
#COMPILER PBCC 4.04
#COMPILE EXE
#DIM ALL
'------------------------------------------------------------------------------------------
TYPE HeapType
length AS LONG
node AS DWORD PTR
END TYPE
'------------------------------------------------------------------------------------------
FUNCTION fLeft(BYVAL i AS LONG)AS LONG
SHIFT LEFT i,1
i = i + 1
fLeft = i
END FUNCTION
'------------------------------------------------------------------------------------------
SUB hpSwap(BYVAL i AS DWORD PTR,BYVAL j AS DWORD PTR)
LOCAL k AS DWORD
k = j
k= j
j = i
i = k
END SUB
'------------------------------------------------------------------------------------------
SUB Fix_Heap(BYVAL hp AS HeapType PTR,BYVAL i AS LONG)
REGISTER m AS LONG,h AS LONG
m = fLeft(i)
h = m + 1
Fix_Heap hp,m
END IF
END IF
END SUB
'--------------------------------------------------------------------------------------------
SUB Fix_Heap_Test()
DIM hp AS LOCAL HeapType
LOCAL i AS LONG
DIM ary(9) AS LOCAL LONG
ARRAY ASSIGN ary() = 9,2,10,12,7,5,8,1,3,5
hp.node = VARPTR(ary(1))
hp.length = UBOUND(ary)-1
Fix_heap VARPTR(hp),0
FOR i = 0 TO hp.length
NEXT 'Should be:12,10,8, 7,5,2,1,3,5 as in the C code.
END SUB
'------------------------------------------------------------------------------------------
FUNCTION PBMAIN () AS LONG
Fix_Heap_Test()
WAITKEY$
END FUNCTION
'---------------------------END OF PB
CODE---------------------------------------
//---------------------------START OF C
CODE---------------------------------------
#include <string.h>
#include <memory.h>
#pragma hdrstop
//------------------------------------------------------------------------------------
typedef struct {
int len;
int node[];
}heap;
//----------------------------------------------------------------------------------------int
fLeft(int i){return (i << 1) + 1;}
//----------------------------------------------------------------------------------------
void Swap(int *i, int *j) { int k = *j; *j = *i; *i =
k;}//----------------------------------------------------------------------------------------
void Fix_heap(heap *hp, int i) { int m = fLeft(i); if (m <
hp->len){ int h = m + 1; if (h < hp->len && hp->node[h] >
hp->node[m]) m = h; if (hp->node[m] > hp->node[i]) {
Swap(hp->node+i, hp->node+m); Fix_heap(hp, m); } } }
//---------------------------------------------------------------------------------------
int main(int argc, char *argv[]) { int i; int ary[]={9, 2, 10, 12,
7, 5, 8, 1, 3, 5}; heap *hp = (heap *) malloc(sizeof(int)*10); //9
elem. + len memcpy(hp, ary, sizeof(ary)); Fix_heap(hp, 0); for
(i=0; i<hp->len; i++) printf(" %i", hp->node[i]); getch(); return
; }//---------------------------------------------------------------------------
Loading...