Video A rchiv (Demo) (m). E in hervorragendes P rogram m zu r Verwaltung der heim ischen Videosam m lung! P ro gram m ie rt wurde es von Uwe Petersen (1. ATARI C lub Colonia e. V.) in G fA-Basic V3.5. Enthalten sind umfangreiche Suchm öglichkeiten, Statistiken und Listen au sgabe, alles nach zahlreichen K rite rien ! Das Program m ist auch allgem ein sehr nett gestaltet und besticht vor allem durch F unktionsvielfalt und einfache Bedienung. D ie Dem oversion entspricht genau der Völlversion, eigene Eingaben können lediglich n ich t gespeichert werden.
B D fln 4/1991 27 |
KURS XE/ST |
M it diesem sechsten Teil schließen w ir unseren C -K urs vor
lä u fig einm al ab. Das Echo a u f diesen Lehrgang war jedoch durchwegs positiv und so könnte es sein, daß der K urs fortgesetzt w ird, vielleich t m it weiteren Pro
gram m iertechniken, vie lle ich t m it Tips & T ricks zu r (^-Program m ierung. Heute befassen w ir uns noch m it den zusammengesetzten Zuweisungsoperatoren und dem modularen Aufbau von C -P ro- grammen. Dazu g ib t es auch wie
der ein fertiges Program m . Zusammengesetzte
Zuweisungsoperatoren
Zusammengesetzte Zuweisungs
operatoren bestehen aus einem binären O perator (das sind jene Operatoren, die zw ei Operanden verknüpfen) und dem einfachen Zuweisungsoperator =.
D ie F unktion dieser Operatoren ist schnell e rklä rt: Sie verknüpfen ihre beiden Operanden nach jener V orschrift, die der binäre O perator angibt. Das Ergebnis w ird dem linken Operanden zugewiesen.
Im P rin zip leisten diese zusam
mengesetzten Zuweisungsoperatoren ja nichts neues, alles schon alter Hut!
Sie erhöhen aber die Ü bersicht
lic h k e it und ersparen (besonders bei langen Veriablennam en) einiges an Schreibarbeit, da der lin k e Operand n ur einm al geschrieben w ird .
-Kurs
Beispielsweise
variablel=variablel*variable2;
lautet unter Verwendung eines zu
sammengesetzten Operators so:
variablel*=variable2;
D ie Operanden dürfen ganzzahli
ge oder float-Typen haben.
Bei den Operanden += und -=
d a rf der lin k e Operand auch vom Typ Z eiger sein. In diesem F all m uß der rechte Operand ganz
zahligen Typ haben. D er Z eiger w ird dabei um jene A nzahl von Objekten (nicht Bytes!) erhöht oder verm indert, die der rechte Operand angibt.
D a m it haben w ir Euch die meisten C-O peratoren vorgestellt.
Rangordnung der Operatoren D ie Rangordnung legt fest, in welcher Reihenfolge bei zusam
mengesetzten Ausdrücken die ein
zelnen Teüausdrücke berechnet w er
den.
P rio ritä t Operatoren_____________ ,
1 Unäre
- ," , !„*&., +H; —, sizeof 2 M u ltip lika tive
* %
3 A ddition und Subtraktion d; ■
4 Schiebeoperatoren
«, »
5 Vergleich a u f Verschieden
<, >, <=, >=
6 Vergleich j •“
7 Bitweises Und Sc
8 Bitweises Exclusive-O der 9 Bitweises Oder
I
10 Logisches Und 8c8c
11 Logisches Oder II
12 Bedingungsoperator
? :
13 Zuweisungsoperatoren
=, zusammengesetzte Stehen in einem Ausdruck m eh
rere Operatoren m it der gleichen P rio ritä t, so w ird im allgem einen von lin k s nach rechts ausgewertet.
Genau um gekehrt ist es jedoch bei drei Gruppen: Bei den unären, beim Bedingungs- und bei den Z u weisungsoperatoren. H ie r e rfo lgt die Berechnung von rechts nach lin ks.
Seid Ih r Euch bei einem ko m p li
zierteren Ausdruck einm al n ich t sicher; setzt soviele K lam m em , bis die Reihenfolge k la r w ird . Bei i f ((A&&B)||(C &&D ))
sind die K lam m em bei (A&&.B) und (C & & D ) n ich t notwendig, erhöhren aber sich die Ü bersicht und zeigen sofort, daß zuerst die U nd-Ver- knüpfungen gebildet werden.!
28 4/1991
KURS | XE/ST
M odularer Aufbau von C-Programm en
Fast jede Program m iersprache bietet M öglichkeiten, Gruppen von Befehlen zusammenzufassen und durch bestim m te Program m befehle ausführen zu lassen. In Basic sind dies die U nterprogram m e und Funktionen. Beide haben jedoch Nachteile: A n U nterprogram m e können keine Param eter übergeben werden, außerdem sind keine loka
len Variablen m öglich. Funktionen hingegen sind im Standard-Basic auf n u r eine Z eile beschränkt
Pascal und C hingegebn erm ög
lichen den m odularen A ufbau von Program m en. M odular bedeutet, daß eine Aufgabe in m ehrere (kleine) Bausteine, sogenannte M o
dule, zerlegt w ird . Jedes M odul kann getrennt getestet werden und sollte genau definierte Schnittstellen zum übrigen Program m haben. In Pascal haben w ir bereits Prozeduren und Funktionen kennengelem t, in C g ib t es n u r Funktionen. Eine Gruppe dieser Funktionen entspricht jedoch genau den Pascal-Prozeduren!
Funktionen in C
Im allgem einen w ird eine Funk
tion so d e fin ie rt:
R eturn-Typ Name (Parameterliste) K örper
Dabei können in bestim m ten Fällen R etum -Typ als auch Param eteriiste weggelassen werden. F unktions
name und K örper sind jedoch unbe
d ingt erforderlich! durch die entsprechenden Werte er
setzt werden.
Nach soviel Theorie aber ein Bei
spiel einer ganz einfachen Funktion:
double hypo(double a, double b) hypo (unser Beispielprogram m be
rechnet die Hypothenuse eines rechtw inkeligen Dreiecks).
D ie Parameterliste ist double a, double b. Sie besagt, daß die Funk
tio n zwei Parameter erw artet, die beide vom Typ double sein müssen.
In unserem Beispiel werden in diese beiden Variablen die W erte 3 bzw. 4 eingesetzt, also a=3 und b=4.
Den Funktionskörper bilden alle Befehle und D eklarationen zwischen den geschwungenen K lam m em . Übrigens: Wenn man Namen als Funktionsnam en auszu
weisen.
Prototypen
Neben der eben vorgestellten M öglichkeit, eine F unktion zu ge
stalten, gibt es noch eine zweite A rt, und zwar die Funktions
deklaration. Sie besteht n u r aus den ersten drei Elementen der Funk- tionsdefinition: R etum -Typ, Name und Parameteriiste, gefolgt von einem S trich pu nkt In unserem Bei
spiel wäre dies
double hypo(double a, double b);
Eine solche Funktionsdeklaration legt einen sogenannten Prototypen fü r die Funktion fest. D er Prototyp
g ib t also an, welche A rt von Para
m etern eine F unktion erw artet und was sie lie fe rt. Intern legt der Com p ile r automatisch beim ersten A u f
treten eines Funktionsnam ens einen Prototypen d a fü r an, auch wenn die
ses erste A uftreten ein Funktions
Dieses Progräm m chen entspricht der Methode drei, der denkbar un der F unktion m ain erfolgen.
U m Methode 2 (D e fin itio n ) anzu
KURS XE/ST |
welche Typen die F unktion erw arten w ird , wandelt also b eim A u fru f die A u fru f definieren oder deklarieren.
Folgende Gründe sprechen dafür;
im m e r Methode 1 zu verwenden:
Erstens erhöht sie die Lesbarkeit des Program mes, denn m an sieht auf einen B lick alle verwendeten F unk
tionen und deren Typen.
Zweitens beginnt die im m e r zuerst ausgeführten F unktion m ain n ic h t irgendwo nach einigen Seiten Pro
gram m code, sondern sie steht am Beginn des Program m es!
D rittens können C -P rogram m e be
ka nn tlich aus m ehreren M odulen bestehen, die unabhängig voneinan
der c o m p ilie rt werden können.
Wenn Ih r also eine F unktion in einem M odul d e fin ie rt und in einem anderen M odul verwendet, enthält jedes M odul, das diese F unktion falschen Typen auf, allerdings erst zu r Laufzeit, da b eim C om pilieren keine Zusam menhänge zwischen den M odulen beachtet werden. W ird jede F unktion im m e r d e fin ie rt, kann das n ich t passieren!
Void
thode, Funktionen ohne Rückgabe
w ert zu definieren.
Bei der Übergabe von Parametern g ib t es übrigens zw ei p rinzip ielle Methoden:
C all by value (W ertübeigabe) und C all by reference (Adreßübergabe).
C verwendet bei Funktionsauf
rufen im m e r die erste Methode, die aufgerufene F unktion bekom m t also eine Kopie der Param eteiiiste.
Diese Kopie kann w ie eine lokale Veriable behandelt werden - Ände
rungen innerhalb der Funktion w irken sich beim aufrufenden Pro Zeigers, da dieser aber Adressen von anderen Objekten enthält, erm ög
lic h t diese Kopie der Adresse genau den gleichen Z u g riff a u f das O bjekt w ie die Originaladresse, also der Zeiger des aufrufenden Program m s.
Zeiger erm öglichen also einerseits, Funktionen zu schreiben, die m ehr als einen Rückgabewert haben und andererseits können m ittels Zeigern auch A rrays und S trukturen an Funktionen übergeben werden.
Beispielprogram m
Im obigen Kasten fin d e t Ih r ein Beispiel fü r eine F unktion m it zwei Rückgabe werten. Sie heiß t swap und hat die Aufgabe, zwei int-W erte zu vertauschen. Das Program m lä u ft natürlich sowohl auf den X L /X E - als auch den S T/TT-M odellen!
In Z eile 5 fin de t Ih r den Funk
tionsprototyp von swap. D ie Funk
tion hat den R etum -T yp void, ent
spricht also einer Pascal-Prozedur.
Weiters erw artet sie zwei Parameter;
die beide vom Typ Z eiger a uf in t sind. In Z eile 9 deklarieren w ir zwei
30 4/1991 B D f lr T l
XE/ST KURS j
tauscht werden sollen. Dies erreicht Ih r durch Anwendung des Adreß-
rär). D er Austausch der beiden Para
m eterwerte e rfo lg t in den Zeilen 18 bis 20.
In directio n-O p erator *
Ih r seht, daß es m it H ilfe des Indirection-O perators * m öglich ist, auf Variable der aufrufenden Funk
tion zuzugreifen., obw ohl C als Kopie des ursprünglichen Zeigers (& i) darstellt - a zeigt natürlich auf das gleiche w ie retu rn.
Rekursive Funktionen Program m iersprachen, die den Va
riablen fix e Plätze im A rbeits
speicher zuweisen, ist Rekursion daher n ich t m öglich, da bei der R ückkehr in eine höhere Ebene die damaligen Variablen von den in späteren A ufrufen benutzten Wer
ten überschrieben werden.
C speichert lokale Variable in einem speziellen Bereich, dem so
genannten Stack (Stapelspeicher;
jaja, kennen w ir aus dem Assemb
ler-K urs!). Dieser w ird dynam isch (zur Laufzeit des Programmes) ver
waltet. Daher sind rekursive Funk
tionsaufrufe im P rinzip in jeder
D ie Lebensdauer einer Variable oder Funktion ist jene Zeitspanne während der Program m ausfüh
rung, in der diese Variable bzw.
Funktion existiert. Funktionen exis
tieren ja ohnehin während des ganzen Programmes.
Bei den Variablen unterscheidet man zwischen globalen (weiden außerhalb jedes Blockes d e fin ie rt und existieren während der ganzen Laufzeit) und lokalen (weiden innerhalb eines Blockes d e fin ie rt und existieren n ur in diesem Block). W ird also der Block, in dem eine lokale Variable d e fin ie rt wurde, verlassen, so ve rlie rt die Variable ihren Speicherplatz und daher auch ihren W ert. D ie Aus auch die Sichtbarkeit einer Variab
len verändert weiden. D ie W irkung von static ist davon abhängig, ob es auf eine globale oder lokale Va
riable angewandt w ird . Bei lokalen Variablen bew irkt static, daß einer solcherart deklarierten Varieble dauerhafter Speicherplatz zugewie
Vom Standpunkt der Lebensdauer ist es also egal, ob m an eine Variable lokal m it static oder global d e fin ie rt.
D er Unterschied lie g t jedoch in der Sichtbarkeit.
S ichtbarkeit
U nter der Sichtbarkeit einer Va
riablen versteht m an die Aussage da
rüber, welchen Teilen des Program den ersten B lick als V o rteil erscheint, die Ü be rsich tlichke it jedoch m in dert. Wenn es n u r darum geht, einer Variablen dauerhaften Speicherplatz zuzuweisen, ist eine m it static dekla
rie rte lokale besser Wenn aber viele Funktionen a uf eine Variable zugrei
fen, ist eine globale sinnvoller register und auto
D ie Speicherart register kann n u r bei lokalen Variablen angewandt weiden und b ew irkt, daß diese n ich t im R A M , sondern d ire k t in einem Register des Prozessors abgelegt weiden, was die Program m ge
schw indigkeit natüriich erhöht. D ie Speicherklasse auto bekom m en alle lokalen Variablen, die n ich t als extern oder static d e fin ie rt wurden.
So, w ir hoffen, Ih r hattet Spaß am
KURS X E |
- K u r s HE T e il
q-In der letzten Folge des BDAC- Assem blerkurses haben w ir unter anderem die Adressierungsarten unm ittelbar, absolut, Zero-Page und in d iz ie rt kennengelernt. Heute setzen w ir an dieser Stelle m it weiteren Adressierungen fo rt.
Nachzutragen wäre, daß es auch bei der Zero-Page-Adressierung eine ind izie rte Adressierung gibt. Dabei werden die bekannten Vorteile der Zero-Page-Adressierung a uf die ind izie rte übertragen. E in ent
sprechender Befehl würde so aus- sehen:
LD A $B A ,X
In d ire k t in d izie rte Adressierung Die in d izie rte Adressierung haben w ir schon in den B D A N 3/1991 ken- nengelem t, h ie r k o m m t je tz t noch die ind ire kte h in zu . Bei dieser A rt spielt die Zero-Page w ieder eine große R olle. D abei bilden zwei a uf
einander folgende Speicherstellen in der Zero-Page einen Z eiger auf die Ergebnis: A enthält den W ert $4E In Basic würde dieser Befehl so aus- sehen:
A=PEEK(PEEK(112)+256*PEEK(11 3)+Y)
D ie indizierte Adressierung w ird dadurch gekennzeichnet, daß der Operand in K lam m em gesetzt w ird. Diese Adressierungsart ist sehr leistungsfähig, denn m an kann m it einem Zwei-Byte-Befehl a uf den kompletten Speicher zugreifen.
Auch diese Adressierung w ird (wie die indizierte) bevorzugt bei Tabel
len- und Schleifenbearbeitung be
nutzt. Sie ist aber fle x ib le r als die einfach indizierte, da man h ie r n ich t n u r auf eine Page, sondern wie schon gesagt, a uf den ganzen Speicher zugreifen kann. Dazu m uß lediglich der In h a lt des 2- Byte-Zeigers in der Zeropage ver
ändert werden.
In d iz ie rt indirekte Adressierung Nehmen w ir an, die Zero-Page-
Adresse $70 enthält den W ert $20, die Adresse $71 enthält $C8. Diese beiden Speicherzellen bilden also einen Z eiger a u f die Adresse $C820.
Zusätzlich ko m m t aber noch die In dizieru ng durch das Y -R egister hinzu. E nthält das Y -R egister z. B.
$B3, so w ird dieser W ert zu $C820 addiert und w ir erhalten als effektive Adresse $C8D3. B ild lic h :
rung arbeitet im Gegensatz zu oben beschriebenen in d ire k t indizierten n ich t m it dem Y -, sondern m it dem X-Register.
Auch h ie r bilden w ieder zwei aufeinanderfolgende Adressen in der Zero-Page einen Zeiger a uf die eigentliche Adresse. Bei der Be
rechnung der Adresse w ird jedoch zunächst der Index zu diesem Zeiger addiert und anschließend die Inhalte der daraus erhaltenen A d
ressen als Zeiger benutzt. Auch zu r in d iz ie rt indirekten Adressierung wieder ein Beispiel: Ergebnis: A enthält den W ert $A9 Das wäre in Basic erhaltenen Adresse sowie der folgen
den w ird der Z eiger a u f die effektive
lic h besprochenen Ladebefehlen sind die Speicherbefehle. D a m it können gegebene Speicherstelle abgelegt A ls Adressierungsarten stehen dieselben w ie bei den Ladebefehlen zu r V erfü
gung, n a tü rlich m it Ausnahme der unm ittelbaren Adressierung, da beim Abspeichem im m e r eine Ad
resse angegeben werden m uß, an die der R egisterinhalt gespeichert w ird . Da b eim Speichern von R egisterin
halten sich an den Registern selbst nichts ändert, werden auch keine Flags b e e in flu ß t.
D er entsprechende Basic-Befehl wäre n a tü rlich POKE. Dazu einige Beispiele, jew eils m it Assem bler- und Basic-Befehl:
STA $8000 PO KE 32768,A STX $C020,Y PO KE 49184+Y,X S TY $F1 PO KE 241,Y
32 4/1991 B D fln
XE KURS |
D ie Speicherbefehle sind also je nach Adressierungsart w ieder 2- oder 3-Byte-Befehle.
M it den Befehlen zum Laden und Speichern haben w ir bereits zwei w ichtige Gruppen kennengelem t, die der K o m m u nika tion des Pro
zessors m it dem Speicher dienen.
Transferbefehle innerhalb des Prozessors unverändert, der W ert w ird lediglich in das Z ielreg ister k o p ie rt Bei den Transferbefehlen innerhalb des Pro
zessors is t bis a uf eine Ausnahme im m e r der A kku b e te ilig t Ein d i
rektes Kopieren von X nach Y oder um gekehrt is t n ichtm öglich.
A lle Transferbefehle sind E in- Byte-Befehle, sie brauchen keinen Operanden. Sehen w ir uns die Be
D er um gekehrte Befehl zum obigen.
D er In h a lt des X-R egisters w ird in
Das sind die entsprechenden Befehle fü r das Y-R egister. D ie Funktionen
entsprechen genau den oben be
schriebenen, n u r ist h ie r das Y - statt des X-Registers betroffen.
Die nächsten beiden Transferbe
fehle betreffen den Stack P ointer W ir erwähnen sie h ie r der V o ll
ständigkeit halber, obwohl w ir a uf den Stapelzeiger erst später näher eingehen werden. D er Stack Pointer kann n u r m it dem X -R egister aus
Die arithm etischen Befehle
Jetzt lassen w ir den Prozessor rechnen. D er 6502 beherrscht Ad
dition und Subtraktion. Jeder Rechenvorgang benötigt zwei Ope
randen, die m iteinander verknüpft werden und lie fe rt daraus ein E r
denen Adressierungsarten z u r Ver
fügung. Das Ergebnis w ird im m e r im A kku abgelegt Z um besseren Verständnis sind w ie im m e r die Basic-Befehle angeführt.
Betrachten w ir zunächst die A d di
tio n. Dabei w ird der In h a lt der adressierten Speicherstelle zum A k kum ulator addiert und das Ergebnis wieder im A kku abgelegt. B it darstellen. Anders h ie r
D er A k k u enthalte $E4. der nächsten Folge erfahren w ir wei
teres über die A ddition, hören von der Subtraktion und beschäftigen uns m it logischen Befehlen, Ver
gleich sbefehlen, Befehlen zur be
dingten Verzweigung, usw. Bis dann!
(dik. D ata Becker)