PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Grundwissen Subroutinen



Zeroeightfifteen
13.03.2006, 17:05
Hallo
was bedeuten denn diese Bytes in der Sub?
Declare Sub Test(b1 As Byte , Byval B2 As Byte)

Wo liegt denn der Unterschied wenn ich die Sub declariere oder wenn ich gleich gosub schreibe.

ich verstehe nicht ganz was dieses Beispielprogramm so richtig macht.
warum declarieren die B1 und B2?


Dim A As Byte , B As Byte 'dimension some variables
Declare Sub Test(b1 As Byte , Byval B2 As Byte)'declare the SUB program
A = 65 'assign a value to variable A
Call Test(a , 5) 'call test with parameter A and constant
Test A , 5 'alternative call
Print A 'now print the new value
End

Sub Test(b1 As Byte , Byval B2 As Byte) 'use the same variable names as 'the declared one
Print B1 'print it
Print Bcd(b2)
B1 = 10 'reassign the variable
B2 = 15 'reassign the variable
End Sub

x-ryder
13.03.2006, 17:44
also die b1 und b2 stehen für übergabeparameter, so nennt man die, d.h. wenn du die sub mit call Test(1,2) aufrufst, wird erstmal in b1 ne 1 gespeichert, und in b2 ne 2, dann kannste das in der subroutine weiterverwenden, also kannste schreiben "print b1*b2" udn der wird dir 2 ausgeben, weil 1*2 = 2 iss...

ich hoffe das iss soweit klar, die haben das dann noch erweitert, so dass die gesagt haben, die zweite variable iss byval, die erste iss (dadurch, dass das der standard ist) byref
byval heißt, dass nur der wert übernommen wird, aus der übergebenen zahl, und bei byref wird die gesamte referenz übergeben, also der speicherort, wo die variable drinliegt. d.h. in die b1 kann man jetzt auch was reinschreiben, weil der ort der speicherung bekannt ist, und dieser ort nun neu beschrieben werden kann, daher wird beim print a auch 10 ausgegeben werden, die b1 wurde ans a zurückübergeben, da die beiden die selbe speicheradresse teilen.

das mit dem gosub ist etwas älter, und das gibts auch in vielen anderen leichten programmiersprachen, aber da gibts eben nicht den vorteil, dass du sagen kannst: ich möchte jetzt diesen wert mit übergeben, so dass du damit weiterarbeiten kannst.

hastes alles verstanden? iss nen bissl schwer zu erklärn, aber ich versuchs gern nochmal anschaulicher ^^

Martin

Zeroeightfifteen
13.03.2006, 19:59
danke schon mal für die Erklärung

doch warum ist der gosub Befehl nicht besser? hier kann ich ja mit allen Variablen die ich am Anfang mit dim deklariere benutzen.
also schreibe ich b1 = 1 und b2 = 2 dann kann ich das ja in der gosub benutzen.

x-ryder
13.03.2006, 20:01
die beiden vars b1 und b2 sind nur in der subroutine aktiv, so kann man außerhalb der subroutine die variablen noch deklarieren, so denke ich, dann gehen die nich verloren

außerdem iss ne subroutine viel übersichtlicher ^^

Martin

Roberto
18.03.2006, 23:13
>>außerdem iss ne subroutine viel übersichtlicher ^^
braucht aber auch mehr Speicher !!

-tomas-
19.03.2006, 09:24
Gosub Test
und
Declare Sub Test() : Call Test()
sind vom Speicherbedarf identisch, wenn keine Parameter übergegen werden.
Gosub ist nur die alte Schreibweise.

x-ryder
19.03.2006, 09:25
declare brauchtn stückn mehr stack, aber das iss nich das ding...

Martin

PicNick
19.03.2006, 09:41
Was ins Fleisch geht, ist die Sache mit "byval". Denn da findet ein Copy in das Frame statt, und das tut weh, abgesehen mal vom Platz. Muß man halt leider angeben, wenn man auch nur ein einziges Mal eine Konstante übergeben will.
Sonst kann man sagen, declare und all-argumente nur dann, wenn die SUB re-entrant sein soll, also wenn sie sich zum Beispiel selbst aufrufen will. Sonst ist es sparsamer, die Argumente in globalen DIM's anzulegen, genauso wie ev. LOCAL's.
Schön strukturiert ist das halt dann leider nicht.

Roberto
19.03.2006, 10:08
>declare brauchtn stückn mehr stack, aber das iss nich das ding...
Ein Aufruf brauchte bei mir ca. 30 Byte mehr Speicher als mit Gosub.
Wenn ich das 20mal aufrufe , habe ich schon 600byte umsonst verschenkt.
Da bleibe ich lieber bei den Gosubs.
Ist dann zwar nicht so übersichtlich aber dafür sparsamer.

ruediw
19.03.2006, 23:19
>declare brauchtn stückn mehr stack, aber das iss nich das ding...
Ein Aufruf brauchte bei mir ca. 30 Byte mehr Speicher als mit Gosub.
Wenn ich das 20mal aufrufe , habe ich schon 600byte umsonst verschenkt.
Da bleibe ich lieber bei den Gosubs.
Ist dann zwar nicht so übersichtlich aber dafür sparsamer.

Du rechnest falsch ...
Nach jedem Aufruf deiner Subrutine werden die Variablen auf dem stack wieder freigegeben. Scheinbar hast Du die Wirkungsweise des Stacks noch nicht ganz verstanden...
Ausser Du rufts deine Subrutine rekursiv auf...
Dann dürftest Du in kurzer Zeit ein grösseres Problem haben.

Roberto
20.03.2006, 07:05
Hallo Ruedi

Ich meine den Programmspeicher!

Wenn ich einen Code habe wo 20mal auf eine Sub zugegriffen wird,
(nicht in einer Schleife sondern wo 20mal der Code drinn steht)
brauche ich ca. 600 Byte mehr Programmspeicher, als wenn ich es mit Gosub Sprüngen mache.

ruediw
20.03.2006, 20:45
@Roberto:
Kannst Du mal diesen Code posten ?
Nur so interessenhalber ...
Danke !

Roberto
20.03.2006, 22:59
Hallo Ruedi

Weis jetzt nicht mehr so genau.
Ich galube ich hatte das mit Functionen probiert.

Habe mal schnell einen Code zusammengeschrieben..

Der braucht 40 Byte mehr pro Functions aufruf als das gleiche mit Gosub:




' 8MHz Quarz
' LCD auf Port B ,
'
' $sim

$regfile = "m16def.dat"
$crystal = 8000000 ' (RC Intern)
$baud = 9600

$hwstack = 256
$swstack = 256
$framesize = 256


'---Config für LCD Port B ----------
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.5 , Db6 = Portb.3 , Db7 = Portb.4 , Rs = Portb.7 , E = Portb.6
Config Lcdbus = 4
Config Lcdmode = Port
Cursor On
'-----------------------------------


Dim A As Byte
Dim B As Byte

B = 10

Declare Function Test(byval C As Byte)as Byte


Do
A = Test(b) ' 500Byte Programmspeicher
A = Test(b) '+ 40Byte
A = Test(b) '+ 40Byte
Loop
End


Function Test(byval C As Byte) As Byte
C = 10

End Function




Und das Gleiche hier mit Gosub:




' 8MHz Quarz
' LCD auf Port B ,
'
' $sim

$regfile = "m16def.dat"
$crystal = 8000000 ' (RC Intern)
$baud = 9600

$hwstack = 256
$swstack = 256
$framesize = 256


'---Config für LCD Port B ----------
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.5 , Db6 = Portb.3 , Db7 = Portb.4 , Rs = Portb.7 , E = Portb.6
Config Lcdbus = 4
Config Lcdmode = Port
Cursor On
'-----------------------------------

'-----------------------------

Dim A As Byte
Dim B As Byte
Dim C As Byte

B = 10


Do

Gosub Test '454 Byte
A = C

Gosub Test '466 Byte
A = C

Gosub Test '478 Byte
A = C

Loop
End

Test:
C = 10
Return

'-----------------------------



Bei 3 Aufrufen mit 478Byte Programmspeicher.

-tomas-
21.03.2006, 00:10
@Roberto
Du vergleichst Äpfel mit Birnen

siehe oben:

Was ins Fleisch geht, ist die Sache mit "byval".
lass die Paramerübergabe byval weg und es kommt auf das gleiche raus