••« r - —~>, -f-^ • '* s-*v=ir^-i-^~«""' • * • — ' * - -:-T~ -.-v'^-si^~^r^ •r^-rrf.v'- -r-.af* -< *^e-v^f,^. r.-y •*:!'• *. j^_—»s-.— • * . "»."..i-•-:.- "• • 'W 'v..-..-.." ;.-syy;V~£-ir ni - c C - COMPILER v c. . j. 3 < O von Di D!.- Math. G. Kerstin^ / H. Rose $'KI~T C . ' "'" -II COPYRIGHT (C) COPYRIGHT G. KERSTING / H.ROSE, 1983 Kein Teil des C - Compilers MI - C ocer dieses Handbuches darf ohne schriftliche Erlaubnis durch die Autoren in irgendeiner Form reproduziert oder verbreitet werden. Des ?Copieren der Disketten ist nur dem Lizenznehmer, und zwar ausschließlich zum Zwecke dsr Datensicherung, gestattet. Alle Rechte vorbehalten. GEUÄHELZIS7UNGS3EDINGUNGEN Uir übernehmer, für den C - Compiler HI - C die Gewährleistung für 6 Monate. Innerhalb dieser Zeit werden zum MateriaUcostenpreis Fehler von uns korrigiert oder das fehlerhafte Progranm ersetzt. Der Käufer des C - Compilers MI - C verzichtet ausdrücklich auf jede Schadenersatzforderung, falls im Zusammenhang mit dem C - Compiler PII - C Verluste oder Ausgaben entstehen, oder ei nicht in der Lage ist, den C Compiler ~I - C für bestimmte, gleichgültig welche Zwecke zu verwenden. Die Autoren behalten sich das Recht vor, am Handbuch und am C - Compiler MI - C Änderungen vorzunehmen, ohne Verpflichtung diese Änderung irgendeiner Person bekanntzugeben. EINFÜHRUNG C ist eine universelle Programmiersprache!, die sich für vielfältige Anwendungen anbietet. Unter anderem ist es nöglich, maschinennahe effiziente Programme zu erstellen, die sonst in Assembler geschrieben werden Büßten. Die Sprache C ist ausführlich beschrieben in: THE C PROGRAMMING - LANGUAGE BRIAN U. KERNIGHAN DENNIS M. RITCHIE ZNGLEUOOD CLIFFS NEU JERSEY PRENTICE - HALL 1978 Eine deutsche Übersetzung dieses Buches i.:rt erhältlich: J • PROGRAMMIEREN IN C KERKIGHAN RITCHIE MÜNCHEN WIEN CARL HANSER VERLAG 1983 Das Buch enthält u.a. eine Einführung in C. Zum Verständnis sind nur geringe Kenntnisse der Programmierung «rforderlich, (z.B. was ist eine Schleife, Variable), die mit der Kenntnis =iner anderen Programmiersprache gegeben si Der Compiler MI - C hält sich an die dort festgelegten Definitionen. Eventuelle Unterschiede zu anderen C Compilern, Erweiterungen und Einschränkungen können im Kapitel E nachgelesen werden. In diesem Handbuch wird zum einen die Handhabung des Compilers MI - C erklärt zun anderen eine kurze Beschreibung der Sprache C gegeben. Auf Dinge von speziellem Interesse wird ab Kapitel E eingegangen. In Kapitel K befindet sich eine alphabetisch geordnete Fehlermeldungsliste mit ErJcläruncen. ni -er" v 3.18 Vfg; DATEIEN L i s t e der D a t e l e n auf der D i s k e t t e ABBRUCH . BEISPIEL .C cc .con ccz .COH - •• CC.SUB CCA .SUB CFLIB .AS« CFMDIVZ.REL CFU1WAND . CHAIN .C CHAIN.REL CIO.C CIO-KURZ .C CIOKURZ .REL CLIB .ASM CLIBZ .ASM -CLIBZ.REL • • CLLIB .ASil CONIO .H CON 10? .H . CSTART.CC H i l f sprogramn für KomoaDdofoLgen Beisplelprogramn KI - C Compiler 8080 - Version KI - C Compiler Z80 - Version Beispiel e i n e r K o m m a n d o f o l g e Assemblerquelle der GleitJcoaiEabibliotheJ: Enthält sdnellere G l e i t k o n m a d i v i s i o n für Z80 A s s e n b l e r q u e l l e der GieitJcoismazahlenuin- wandlungen Aufruf eines Nachfolgeprogramms C-Quelle der unf ormatierten Ein- Ausgabe C-Quelle der unformatierten Ein- Ausgabe (Kurzversion) A s s e m b l e r q u e l l e der I n t e g e r - B i b l i o t h e k Z80 - V a r i a n t e für die I n t e g e r - B i b l i o ü i e k Asseniblerquells der Long-Bibibliothefc Enthält Einstellnöglichkeiten für die TerEinalbehandlung V e r s t o n für die LI3P .REL i n c .^ Ä t p i > « «v V» ^ V W ^ £ ü T~ d^n ^ U — •« •— ü A n ^ r*~» i u n A t U ^ ^>« * «^ *• ^ von LIB.HZX CTEST .C IODEF.C •- '' C-Quelle T e s t - , S t r i n g - , System- und Speicherverwaltungsfunktionen H i l f s d a t e i , die bei Ä n d e r u n g e n an der Bibliothek b e n ö t i g t wird IODEFP .C IPRINTF.REL LIB.HEX LI3.REL LI3K.REL LI3P.REL fiATH.REL STDIO.H STDIO-KU.RZ r~ i *. > T /~\ •"« i • si^IOr .n j. RACf F . AStt XXXrtAIN.HAC XXXrtAIN .REL XXXRAINZ.nAC XXPPLMN.REL ZAHLEN .C ZBG.C ZBG.DOC Kurze Version der formatierten Ausgabe, ohne l o n g , f l o e i t , d o u b l e . L a u f z e i t b i b l i o ' i h e k ( f ü r ASH.COM K u r z v e r sion ) L a u f z s i t b i b l i o t h e i c ( f ü r MAC8C / L 8 0 ) Laufzeitbibliothek (KurzVersion) L a u f e i t b i b l i o t t e k ( f ü r Option . ) Mötheic. F u n k t i o n e n : t r i g o n c m e t r . logar i t h m . t exponer t . D e f i n i t i o n e n für die Ein- Ausgabe Definitionen f ü r die verkürzte I/O Definitionen zur LIaP.RtL assecblerquelle für den Trace Initialisierung I n i t i a l i s i e r u n g zur LIBP.REL • Beispielprogramne für die Zahlenausgabe ZBG2 .C ZBGDEF .C Z5GI)rX7.C Erklärung in ZBG.DOC Eeispie iprogramm *;"-.. .'iJL ~ V. J. t * •i INHALTSVERZEICHNIS " 'Seite A. Einige Eigenschaften des CC'inpilers MI - C B. Die Arbeit mit dein Compiler . .A l 3 l I. Aufruf, Protokollierung, Optionen, Trace . . . B l II. Beispiele zur Compilaticn B a. M i t Linker b. Ohne Linker X N. 4 B 4 B 5 C. Kurze Beschreibung der Spreche C .C l I. Namen, Schlüsselworte, Konstanten, Strings, Trennungszeichen, Kcmmentaie C l 11 N a m e n 12 S c h l ü s s e l w o r t e 13 K o n s t a n t e n I3a G a n z z a h l i g e K o n s t a n t E - n I3b Z e i c h e n k c n s t a n t e n I3c G l e i t k o m m a ( F l o a t ) k o r . s t a u t e n 14 S t r i n g s C C C C C C C l 2 3 3 4 5 6 15 Trennungszeichen C 7 16 Kommentare C 7 C 8 C C C C 10 13 14 18 II. 111 112 113 114 Deklarationen Spei eher k lassen Typ und arithmetische Umwandlungen Felusr, Pointer, struct unc. union Initialisierung • III. Ausdrücke C 20 1111 Primäre Ausdrücke .• 1112 Ausdrücke m i t Operatoren C 20 C 21 1113 Konstante Ausdrücke C 27 - .. V *" MI - C IV. Anweisungen C 28 IV! if - eise C 28 IV2 IV3 IV4 switch while for C 31 C 32 C 33 IV5 do - while C 34 IV6 break C 35 IV7 IV8 continue return C 35 C 36 IV9 label IV10 goto C 37 C 37 IVll leere Anweisung C 38 IV12 Blockanweisung IV13 Ausdruck - Anweisung C 38 C 38 V. Externe Definitionen . . . C 39 VI Externe Datendefinitionen V2 Externe Funktionsdefinitionen C 39 C 40 j » •i VI. Die Funktion inain C 41 VII. Anweisungen an den Preproc-~ssor C 42 VIII Ersetzungen ( 2define ) VII2 Einfügen von Dateien ( #inc:lude ) C 42 C 42 VII3 Bedingte Coapilation ( £if, »ifdef, #ifndef ( ! #else, #endif ) . C 43 VII4 Ändern der Zeilennumnier ( * line) VII5 Einfügen von Asseinblertex ttm ( £asm C 44 #endasm ) . C 44 VIII. Regeln für den Geltungsbereich von Objekten . C 48 D. Beschreibung der Bibliothe)sfunktionen . . . . D l I. Unfornatierte Ein- Ausgabe l 11 Ein- Ausgabe für das Ter^irai 12 Geoufferte Dateiverarbeiturg-* * 13 U n g e p u f f e r t e D a t e i v e r a r b e i t u n g II. III. IV. V. F o r m a t i e r t e E i n - Ausgabe Allgemeine Systemfunktioner Stringfunktionen T e s t - und U m w a n d l u n g s f u n k t i o n e n D D l D D 2 5 D D D D 7 13 14 16 VI. VII. Speicherplatzverwaltung Mathematische Funktionen D1S D IS Liste der Einschränkungen, Erweiterungen und Besonderheiten - E F. Zahlendarstellung F \ G. Geschwindigkeitsoptim ierung ......... G l K. A n s c h l u ß von AssemblerprograEDsr. an C Programme und A n s c h l u ß von C - r u n / c t i c n e n an a n d e r e Programme ............. H l I. Sy stsagrößen I l J. H a r d w a r e und S o f t w a r e V o r a u s s e t z u n g e n K. Fehlermeldungen E. r* .............. ................. Ueitere Unterstützun Stichwortverzeichnis . . . . J l K l ............... I. F e h l e r m e l d u n g e n des C o m p i l e r s I I . L a u f z e i t f eh l e r m e l d u n g e n des B e n u t z e r s l ........ ........... ........ K l K 10 L l IT _ A' l' A . E I N I G E EIGENSCHAFTEN DES COMPILERS E i g e n s ch a f t en MI - C Der Compiler MI - C erstellt aus eine^m In einer Datei vorliegenden C Quell Programm eine Datei mit 8080 oder Z80 Assemblercode. Mittels eines Assemblers wird dann daraus eine Datei mit Maschinencode erzeugt. Der zum CP/M System gelieferte Assembler ASM.COM ist ausreichend. Kehr Komfort bietet eine Kombination von Assembler tnd Linker (speziell MAC80 und L80 von Microsoft), deren Gebrauch vom Compiler besonders unterstützt wird. MI - C ist benutzerfreundlich, und mit dem Compiler erstellte Programme sind schnell und )curz. Der Compiler gibt optimierten Code aus. Z.B. wird ein Ausdruck aus Konstanten bereits während der Cocpilation ermittelt, eine Subtraktion mit einer Konstanten in ein 2 Addition, eine Addition mit einer kleinen Konstanten in eine Inkrementoperation verwandelt, eine Variable, die sich schon durch eine vorhergehende Operation in einem Register befindet, möglichst nicht erneut geladen. Die minimale Große für ein vollständiges Programm betragt einige hundert Byte. Hervorzuheben ist: - Der Compiler legt eine Fehlerprotokoll - Datei an. Jede Fehlermeldung besteht aus einer wahlweise deutscn- oder englischsprachigen Fehlermeldung und der C - Quellzeile (mit zugehöriger Zeilennumaer), in der cer Fehler aufgetreten ist. Die genaue Fehlerstelle ist markiert. - Der Compiler kann auf Wunsch die C - QueHzeilen als Kommentar mit in die Assemblerdatei ausgeüen. So kann genau verfolgt werden, weicher Code aus den jeweiligen C - Anweisungen generiert wird. - Der Vorgang der Obersetzung des Qu'-llprogramnis kann ani Terninal verfolot werden. Der Nase der cerade übersetzten Funktion wird auf dem ^' ^ Terminal protokolliert. Zusatzlich wird für jeweils 10 Zeilen ein oder 'E' ausgegeben (ein / kein Fehler aufgetreten). Mittels 'control C' kann der Compilerlauf abgebrochen werden. Die Information in den Ausgabedateisn bleibt dabei erhalten. - Ein C - Quellprogramin von 15k Byte Länge wird i.a. in weniger als 3 Minuten (bei 2~Hz) übersetzt. Da keine Assemblermacros erzeugt werden, ist die Assemblierungszeit auch sehr kurz. - Das QuellprocTsmro kann nach belieben in einzelne Teile zerlegt werden (eine oder nshrere Funktionen und cde'r Variablendeklarationen), die dann getrennt übersetzt werden können, wird mit einen Assembler/ Linker gearbeitet, kennen die Teile auch getrennt assembliert werden. In diesem Fall erzeugt äer .Compiler automatisch die nötigen EXT, PUBLIC, DSEG und CSEG Anweisungen für den Assembler, damit der Linker die einzelnen Teile zusammenbinden kann. - Gleitkommazahlen (ficat,double) sind als gepackte 3CD Zanlen dargestellt. Hierdurch entfällt die Ungenauigkeit, die entsieht, wenn cezisaie Gleitkommazahlen binar dargestellt werden. Es wir! immer mit 13 Stellen Genauigkeit gerechnet. - Es steht ein Trace zur Verfügung. Uihrend des Laufes des co~pilierten Programmes werden die Namen der jeweils aufgerufenen Fur.kr.cnen auf dein Terminal ausgegeben, der Uert einer Anweisung mn ~ert (z.B. A= 5;), der Uert eines Testes (z.S. if (A-H-) )t sowie die zur Anweisung gehörige Zeiler.nunuuer des Quellprograinms. Über die Tastatur kann ciie Protokollierung jederzeit ein- und ausgeschaltet werden. **••-•., ?:'-iil - C - Es kennen sowohl Unterprogramme allgemeiner Art als auch direkt lauffähige Programme für CF/fl ( ... .COH -Dateien)) erzeugt werden. Für diesen Fall steht eine Bibliothek mit Ein-/Ausgabefunkticnen zur Verfügung. - Namen von globalen Variablen und Funktionen treten in der Assemblerdatei unverändert auf, was die Feh lerverfolgung vereinfacht und bei Bedarf einfach Manipulationen und Ergänzungen erlaubt. Z.B. wird aus 'VAR = 5;' : LXI H,5 bzw' LD HL,5 SHLD VAR LD (VAR),HL - Der erzeugte Code kann in einen ROr - Speicher gebracht werden. Der Datenbereich kann mittels der Assembleranweisnng 'ORG' oder mit Hilfe des Linkers an eine beliebige freie Stelle des Speichers gelegt werden. - Der Compiler sowie die übersetzten Programme können durch Interrupts aa beliebiger Steile unterbrochen werden. Die Register A, B, C, D, E, F. K, L dürfen dabei nicht verändert werden. Geschieht die Unterbrechung während eines Aufrufes vor. ^DCS, so sind die dcbei gültigen Beschränkungen zu beachten. (3DOS stellt nur einen begrenzten Raum im Stack zur Verfügung. Außerdem könner die Unterprogramme im jeweiligen 3ICS Beschrankungen auferlegen.) 5 . DIE AHSEIT H I T DEfl COMPILER I . A U F R U F , PHOTOKOLLIEHUNG, O P T I O N E N , TRAGE Ein C - Programm besteht aus einer oder mehreren Funktionen. Der Compiler erzeugt daraus Assemblercode Unterprogramm. Das von anderen Pogramniersprachen her bekannte Hauptprogramm ist eine Funktion mit dem Namen MAIN. MAIN wird beim Start eines compilierten und asseinblierten C - Programms automatisch aufgerufen. Der Compiler wird gestartet durch: CC KAKE'cr' ('er' bedeutet RETURN) Das C Quell program m muß in der Datei NAKK.C sein. Es werden die Dateien NAHE.T-AC mit dem Asseniblerprogramm und Nr~E.LST mit den Fehlermeldungen erzeugt. üenn andere Optionen als die voreingestell4:en benötigt werden, kennen sie vor dem Dateinamen emceleitet durch / anceceben werden, z.3.: ~ird gestartet durch CC'cr' ,so fordert der Compiler die benötigte Information an. Diese Form mu3 angewandt werden, wenn die Quell- oder Zieldateien einen anderen Zusatz als .HAC i .ASM) und .C hauen. Es werden solange Eingäbedateien angefordert bis nur HETüRN eingegeben wird. Wird ' bei der Ausgabedatei nichts angegeben d.h. 'er', so wird die Ausgabe am Terrjir.al protokolliert. Während des Laufs des C - Compilers werden die Namen der gerade übersetzten Funktionen auf dem Terminal protokolliert. Hinter dem Namen wird für jeweils 10 fehlerfreie Zeilen ein '-' gesetzt. Erscheint ein 'E' so bedeutet des, daß ir-serhaib dieser 10 Zeilen ein Fenler entdeckt wurde. '-', denen kein Name vorausgeht, gehören zu externen Definitionen. -' . Außer der Ausgabe - Datei wird noch eine F?hlerprotokoil - Datei mit gleiS, chera Namen und dem extend .LST erzeugt. 5:ie enthält die Fehlermeldungen des Compilers ait den dazugehörigen Zeilennummem aus der Ouelldatei. Der Compiler kann durch Eingabe von 'control C' unterbrochen werden. Die Auscjabedateien werden dann vor dem Sorjnj zum Eetriebsr/stsm (U300T) geschlosser.. Die bis zu' diesem Zeitpunkt gewonnene Information geht also nicht verloren. Folgende "Optionen verändern die Compilation: _ A «^ * » Das Pr-rranm wird nur auf Fehler untersucht. Es wird kein Assemblercode ausiegeDen. Wenn kein Ausgabedateiiia^e angegeben wird, werden die Frhlerz=ldung=n auf dem Terminal protokclliert. C Das C CMellprogramm wird als Konirentai mit in die Assenblerdatei ausgegeben, sodaB verfolgt werden kann welcher Assesbiercode aus den jeweiliger. C - Quellzeilen erzeugt wird. L Es wir- keine Fehler rrotokolldatei anoei-:?gt. Fehlermeldungen werden mit in die Assemblercodedatei als Komnentar ausgegeben. T Prograrr.tcile die unter dieser Option übersetzt werden, bekommen Infcr~aticn für den Trace mit. (T setzt automatisch die Ootion X.) ^ 4 — W ~ [ X Eine Anweisung vom Typ Ausdruck hinterläßt ihren Wert im HL Register (beim Typ long in CLPRItt und double :ji CFFKIfl ). Benötigt wird'diese Option nur, wenn mit #asin .. #endasm ^ssemblercode eingefügt wird, und dabei der Wert von einem Ausdruck in dem Assembierteil program m verwandt wird. S Der Wert eines char liegt bei dieser Cptios zwischen 0 und 255 und nicht wie sonst zwischen -128 und 127. (£ bietet sich an, wenn char Variable nicht Zahlen sondern Zeichen dar steilen sollen.) A Diese Option wird benötigt, wenn kein .Jjiker benutzt wird. Die Voreinstellung für die Ausgabedatei ist dann .ASM. Die Ausgabe von externen Bezügen unterbleibt. Außerdem wird eine Labeinummer angefragt (Voreinstellung : OPO; Siehe Beispiele ohne Linker). Unter der Option A gelten zwei Einschränkungen. Statische interne Variablen dürfen nicht initialisiert werden, U2d statische Funktionen müssen vor dein ersten Auftreten deklariert werden. G Die Speicherplatz Definition für nicn* initialisierte Variablen unterbleibt. Im N er E elf all wird diese Option nicht benötigt. . Alle VCD Compiler ausgegebenen Namen (Assemblerlabels) werden mit einem Punkt am Anfang ausgegeben. Nac.enskonflikte mit vom Assembler reservierten ^anen treten dann nicht auf. (z.B. Beim nACSO sind Regist=rnamen reserviert.) Es wird dann XXPKAIN.HEL und LIBP.HEL verwandt. 0 Die Datei -.LST wird bei fehlerfreier Csrnpilation (C Fehlern) gelöscht. : Dem Doppelpunkt muß ein Buchstabe zwischen A und ? einschließlich folgen. Dieser Buchstabe gibt das Laufwerk an, von dem die Quelldatei genommen werden soll. (z.B. A:CC /:3 ClBEISPIEL) D Strings werden unter dieser Option imm-r im Daienbereich abgelegt. Der Platz für Strings ist dann nicht begrenz".. W Bei der Option W kann bei einer switch - Anweisung default an beliebiger Stelle stehen. Dadurch vergrößert sich der ausgegebene Code bei Jedem switch mit default um 2 Sprungs. Ohne diese Option darf nach default kein case auftreten. P In Prograinmtcilen, die unter dieser Option übersetzt werden, wird während des Programmlaufs überprüft, :>b der Stack in den Prccrammoder Datenbereich überlaufen kann. In üesem Fall wird der Programmlauf abgebrochen und eine Fehlerneluun; auf dem Terminal ausgegeben. • Die Überprüfimg geschieht u.a. immer beim Eintriti in eine Funktion. Ais Nebeneffekt bei der Option P ergüt sicn eine Verlangsaisung und Vergrößerung des Programms. Im Norscifall wird diese Option nicht benötigt. Wichtig ist'sie z.B. bei rekurinven Funktionen, die eine hohe Verschachtelungstiefe erreichen kennen. Zum TRAGE : Wenn einem Programm t eil Information für den Trace hinzugefügt ist (Option T), so wird beim Procrammlauf jeder FunKion saufruf auf dem Terminal protokolliert. Außerdem wird bei ^eder Anweisung 'ausdruck;', 'if (ausdruck)', 'while (au5druck)'/for (..;ausdruck;..)'/suitcri (ausdruck)' die Zeilennummer aus dem Quellprogramm und der gerade errechnete üert ausgegeben. Bei ganzzahligem Typ wird er als Dezimalzaiil uni als Hexadezimalzahl ausgegeben. Durch Eingabe des Zeichens 'N' von der Tc Statur wird der Trace ausgeschaltet. 'X' schaltet ihn wieder ein und bei 'T' werden nur die Funktionennamen protokolliert. Die eingegebenen Zeichen erscheinen auch luf dem Terminal. • i r H S PrtH tn II. BEISPIELE ZUR COMPILATION Es werden nun einige mögliche üege zur El "Stellung eines unter CP/M lauf fähigen C-FrogramiDS beschrieben. Progranine, die auf anderen Betriebssystehen laufen sollen, benötigen andere selbst zu schreibende Ein-, Ausgabe und Initialisierung Superprogramme. Bei den folgenden Beispielen bedeuten Kleinbuchstaben die Eingaben vom Terminal und Großbuchstaben die Ausgaben zum Terminal. Nehmen wir an, das C - Queiiprogramm ist in der Datei Z3.C . a. MIT LI-^KER Hier wird die Kompilation L 8 O/K 80 von Microsoft zugrunde gelegt. Bei anderen Produ.lrten wird ähnlich verfahren. Das Lauf zeit System und die Ein- Ausgaben 'ogramme befinden sich in der Bibliotheksdatei LI3.REL. XXXMAIN.REL mu3 immer beiz Linken als erstes a n e e b e n werden. A>cc zb'cr' MI - C v-3.18 (C) COPYRIGHT G. KEH57ING / H. ROSE, 1933 MAIN OUTSTRINNL ;0 FEHLER A>m80 =zb'cr' NO FATAL ERROR(S) A>180 zb/^xxxmain.zb.lib/s/e'cr' Nun haben sie eine Datsi zb.com erzeugt. Da; Programm kann nun durch Eingabe von zb gestartet werden. Befindet sich die Fun:<tion OUTSTRIN in einer anderen Datei (z.B. um Zeit zu sparen, denn bei Programinä'nderungen braucht sie dann nicht mehr neu ccmpiliert werden), und soll sie getrennt übersetzt werden, so geht man wie folgt vor. Der Name dieser Datsi sei ZBOUT.C . A>cc zb'cr' MI - C v-3.18 (C) COPYRIGHT MAIN NL ;0 FEHLE?. A > m 8 0 =zb'cr' NO FATAL ERROR(S) G. KERSTIiNG / H. ROSE. 1983 Hancihabunq A>cc ibcut'cr' HI - C v-3.19 OUTSTRIN;0 FEHLER (C) COPYRIGHT G. KERSTING / H. ROSE, 1983 A>ü)80 = NO FATAL ERROR(S) A)180 zb/n,xxxniain,zb,zbout,lLb/s/e'cr' Es folgt als weiteres Beispiel der Dialog em Terxcinal, wenn sich die Datei ZB.C auf Laufwerk D befindet. A>d:cc'cr' KI - C v-3.18 (C) COPYRIGHT G. KERSTING / H. ROSE, 1983 OPTIONEN C»'=NUH FEHLER 'T'=TRACE ) ? cs'cr' AUSGA3EDATII ? zb.src'cr' EINGASEDATEI ? dlzb.c'cr' . ' KAIN OUTSTRINNL EINGABEDATEI ? 'er' ;0 FEHLER rät Hilfe des Linkers (/D:.... bei L 80 ) kaiin man, auch wenn getrennt compiliert wnrd?, dsn Variablenbersich ans Ence des Programns legen (kleinere .. .COK aöglich), was sich bei der Benutzung von langen nicht initialisierten Feldern e m f i e h l t . b . Als Beispiel wird das Vorgehen mit Hilfe des Assemblers ASn.COr: (von Digital Research zua C?/H mitgeliefert) betrc.chtet. ZB.C enthält ein C Quellprogramm. Direkt als erstes muß die Quelle £incl.ide CSTART.CC enthalten. In CSTART.CC sind u.a. die Definitionen der Eingangspunkte für das Laufzeitsysrem, das sich in L IB.HEX befindet. Sie führen nun den folgenden Dialog: A>cc /a zb'cr' MI - C v-3.18 (0 COPYRIGHT G. KERSTING / H. ROSE, 1933 XA IN 3UTSTRIN ;0 FEHLER A>asin zb.aaz'cr' .-Jddt lib.hex'cr' IDT VERS 2.2 :;EXT ?c :co: -gü 0100 A>save yyy zb.com - l ist die höchste vorkommende Adresse im Maschinenprogramm, aus ier yyy errechnet wird, (yyy ist die Anzahl der Pages.) Das Programm kann nun gestartet werden. -erden Teile der Bibliothek nicht benötigt (z.B. Disk Ein- Ausgabe), so kön-=- sie vom Programm überlagert werden, und dieses dadurch verkürzt weri=n. Das geschieht dadurch, daß eine von 4 vorhandenen Alternativen bei der Assembler- CRG Anweisung am Anfang der Da:ei CSTART.CC aktiviert wird. Besteht das Programm aus mehreren Teilen die getrennt compiliert werden sollen, so darf nur im ersten Teil £incluie CSTART.CC stehen. Außerdem zu.G bei allen Teilen explizit eine Startlabelnummer angegeben werden. las eschieh! folendermaßen : XI - C v-3.13 (C) COPYRIGHT * G. KERS7ING / H. ROSE. 1983 • T C?TIC\ EN C*'=NUH FEHLER 'T'=TRACE ) ? e'cr' « ANFANGS LÄBEL : SOO'cr' Ä'JSGAEEDATEI t zboüt.asTü'cr' E:>:GABEDATEI ? z CUT5THINE::;GA3EDATEI ? 'er' ' 3 FEHLER Nach der Option A wird die Anfang slabeln1 immer erfragt. Sie hat folgende Bedeutung : Der C- Compiler erzeugt Asserablerlabels, d.e die Form Oocooc haben, wobei xxxxx eine Zahl ist (z.B. C200: ). Die gleichen Zahlen dürfen nicht in verschiedenen Programmteilen auftauchen, da, w=nn ohne Linker gearbeitet wird, alle Teile gemeinsam assecbliert werden müssen. Es wird die Anfangszahl angefragt. Die Dateien ZB.ASM und Z30UT.ASH müssen nun gemeinsam assembliert werden. z.B.: A>pip zb.as^zb.asn^zbout.asm'CR' A)asüi zb.aaz'cr' Die Bibliothek liegt auch in Quellform vor. Uenn dort Änderungen vorgenommen werden, oder C - Funktionen als Unterprogramme für andere Programme verwendet werden sollen, so müssen die do.rt aufgerufenen BibliotheksprograiLEe gemeinsam mit diesen Funktionen isserabliert werden. Die Datei LIB.HEX wird dann nicht benutzt. z.B.: Z3.C enthält nicht ^include CSTAIT'.CC ' A>cc /a zb'cr' KI - C v-3.18 (C) COPYRIGHT G. KERSTING / H. HOSE, KAIN OUTS7RINNL ;0 FEHLER \ A-) ^Dl *D ZD *ÖSE —C5"t2-L \. A)asr, zb.aaz'cr' A)load zb'cr' Das Prooranis kann nun Gestartet werden. 1983 C. KURZE BESCHREIBUNG DER SPRACHE C' I. NAHEM .SCHLÜSSELUORTE . KONSTANTEN .STRINGS TRENNUNGSZEICHEN, KOMMENTARE II NAMEN Naaen bestehen aus Ziffern, Buchstaben und dem Unterstreichungszeichen "_". Das erste Zeichen eines Namens mufl ein Buchstabe sein. Nur die ersten t Zeichen eines Namens sind signifikant, er kann aber beliebig lang sein. \c.r;. A3CDE7GK5 und ABCDEFGH100 werden nicht unterschieden) Bei Namen werden Klein- und Großbuchstaben unterschieden, (d.h. ABC ist verschieden von abc) v ^« W 4J U 12 SCHLÜSSELWORTE Schlüsseiwcrte sind Namen, die bereits eint 1 bestimmte Bedeutung haben. Sie dürfen auf keinen Fall anderweitig verwende'; werden. Liste der Schlüssel werte: auto break double case en try extern f loat for char continue default do eise octo if int long regis ter static struct sw i t ch typedef r e turn union short sizecf unsigned while Hei Schlüsselwörter, werden Klein- und Großbuchstaben voa Compiler KI - C nicht unterschieden. ( I N T = int) 13 KONSTANTEN I3a GANZZAHLIGE KONSTANTEN Es gibt drei Arten von ganzzahligen Konstanien: 1. Dezimale, ganzzahlige Konstanten bestehen aus den Ziffern 0 bis 9. 2. Falls die erste Ziffer 0 ist, wird die ganzzahlige Konstante als Oktalzähl aufgefaßt, Die Ziffern 8 und 9 naben dabei den oktalen Wert 10 bzw. 1l. 3. Falls die ganzzahlige Konstante am Anfing die Zeichen OX enthält, wird sie als Hexadezimalzahl aufgefaßt. a oder A bis f oder F entsprechen den dezimalen Werten 10 bis 15. Falls der Wert einer dezimalen Konstanten Kleiner oder gleich 32767 ist, hat sie den Typ int. Ist ihr Uerc größer als 32767, so ist sie vom Typ long. Hexadezimale und oktale Konstanten sind vom Typ unsigned, wenn ihr Uen kleiner oder gleich 65535 ist. Sonst haben sie den Typ long. Eine ganzzahiige Konstante, auf die unmittelbar der Buchstabe l oder L folgt, ist ebenfalls vom Typ long. Der größte Wort einer long Konstanten ist 2147483647. : x — <~i w T ~~ T r" • ~~ ' v^*»i r* •** * >»****~>t i3b ^r.ICr.r.,«K.^j-J5 i A K i t N Zine Zeichr.nkonstar.t6 ist ein in ADostroDh einaeschlossenes Zeichen. z.B. ' A ' , '3', ' C ' , '0'. " * " Der Wert eines solchen Zeichens ist der Wert, den das Zeichen im jeweiligen Maschinen Zeichensatz besitzt. Bei CP/K iirt das der Wert, den das Zeichen iza ASCII - Code hat. Beispiel ' . '0' hat den Uert 30H. '!' hat den Wert 3ih. 'A' hat den Wert 41H. einige nichtucrsisIUDare Zeichen besitzen e.ne Ersatzdarstellung. Im folgender, cüe Ausnahmen und ihre Darstellung als ZeichenXonstante: Name . Schrägstrich (bacJcslash) Rückwärtsschritt (backspace) Uagenrucklauf (carriage return) Se itenvcrschub • • Zeichen Darsisllunc als Ze icheiKonstants \ '\\' BS '\t>' CR '\r' FF '\f i (form feed ) horizontale Tabulation (horizontal tab) neue Zeile (neu l ine) Apostroph (single quote) 7A3 HT '\t' t j j ' KL (LF) * • '\n' . '\" Außerdem kann ein binarer Wert unmittelbar als oktale Kcnsranie angegeben werden. '\zsz' ist Zeichenkonstante, wobei zzz l, 2 oder 3 oktale Ziffern sein können, z.3. ist '\0' die binäre Null Ihr üert ist G. ( I m Gegensatz zur Zeichenkonstanten '0', die den Wert 3OH besitzt.) Zeichenkonstanten sind stets von Tvo int. j ! | ; | j j I3C GLEITKOMMA ( F L O A T ) KONSTANTEN Eine Gleitkorcmakonstante besteht aus eineij ganzzahligen Teil, einem Dezimal punkt, einem gebrochenen Teil und eirem e oder £ gefolgt von einem Exponenten mit oder ohne Vorzeichen. Wenigstens eines von beidem: DezimalpunJct oder E (e) mit Exponent mu3 vorkomnen. Ebenso muß wenigstens eines von beidem ganzzahliger oder gebrochener T.JÜ vorkommen. Beispiel 3.4567E50 6.0 G .033 . s9 ist Gleitkommazahl ist Gleitkommazahl nicht, weder . noch E oder e ist Gleitkommazahl nicht, weder gar.izadliger noch gebrochener Teil Gleitkomma Konstanten sind stets vom Typ doible. 14 STHINGS Ein String ist eine Folge von Zeichen, die in Anführungsstriche eingeschlossen ist. Der Uert eines Strings ist ein Pointer, der auf ein Feld zeigt, das ciie zwischen den Anführungsstri:hen stehenden Zeichen enthält gefolgt von einer binären Null. Die Ersätze arstellungen suid dieselben wie bei den Zeichenkonstanten. (z.B. \B für BcCkspace) zeicht sinnvoll ist \0, da hierdurch der String beendet würde. Falls im String selbst das Zeichen " vorkonmen soll, muß ihm ein \ vorangehen! • EeiSDiel "DIES IST EIN STRING" 15 TRENNUNGSZEICHEN Trennungszeichen (Leertaste (blank), Tab, Neue Zeile (neu lins)) werden ignoriert. IG KOKKENTARE Kommentars müssen mit /* beginnen und werden Bit */ beendet. Kommentare können auch über mehrere Zeilen gehen. BeiSDiel /• DIES IST EIN KOnÜENTAH */ v,/ II . DEKLARATIONEN Der C - Compiler kann nur Objekte verarbeiten, ciie vorher deklariert wurden. (Ausnahme: Ein unbekannter Name, auf den ' ( ' folgt, wird automatisch als Name einer int Funktion definiert.) Mit Objekt ist ein Bereich im Speicher gemeint. Deklarationen sehen allgemein so aus: Speicherklasse Typangabe Liste von Deklarieren ; Uemgstens eines von beidem Speicherklasse oder Typ muß in einer Deklaration vorhanden sein. Fehlt die Angabe eines Typs, so wird automatisch int angenommen. EeisDiel int VA, V5, VC; static int VD; Typ 3 Cb3-e;rte ; Speicherklasse Typ l Objekt Die Typangabe besteht aus einem der auf d--n folgenden Seiten angegebenen arithmetischer. Typen, einer Union- oder Strukturangabe oder einem DatentvD, Geschaffen wurde. * * * der mittels tyuedef * A Deklaratcren sind Namen, zu denen die Ze.chsn [], 0, « treten können, wodurch eine theoretisch unbegrenzte Anzahl abgeleiteter Typen definiert werden kann. C] bedeutet Feld vom Typ ... i ( ) bedeutet Funktion, die Typ ... zurückliefert * bedeutet Pointer auf den Typ ... Außerdem besteht noch die Möglichkeit mirtels struct ... { } oder union ... { } solche Obiekte zu einer Einheit zusasmeizusetzen. Hier einige Beispiele: v BeisDiele int VA; die Variable VA ist vom Typ int int »VA; VA ist Pcinter auf eine Variable vom ?yp int, »VA bezieht sich auf diese Variable und VA enthält die Adresse von »VA - int V A ( ) ; VA ist eine Funktion ohne Parameter, int MÄX(A,3) (returnA<3 ? E:A; } MAX ist eine Funktion mit Parametern, die einen Usrt vom Typ int zurückiiefert long (*VA)(); VA ist ein Pointer auf eine Funktion, die einen Wert vom Typ long zurückliefert cter VA L33; VA ist ein Feld, das drsi Elemente vom Typ char er.trjäit i V A C 0 3 , VAC13, VAC23 ) int » V A C 3 3 ; VA ist ein Feld, das drei Pointer auf TJe:te vom Typ in: enthält int < » V A ) C 3 3 ; VA ist ein Pointer, auf ein Feld, das drei üerte vom Typ int enthält .int Q C 2 3 C 3 ] [43; Q ist ein dreidimensionales Feld (2x3x4) - C C 9 Icng »*VLP; ist ein Pointer auf einen Pointer auf ein Objekt vom Typ long. Struct CCHNELIA *( *( «VC ) [33 ) O; VC ist Pointer auf ein Feld, das aus drei Pointern auf Funktionen, die Pointer auf eine 5tru)ctur vom Typ CORKELIA zurückliefern, besteht. Die Klammern in den Beispielen sind nötig, da die ModifiJcatoren verschiedene Priorität haben. 0 und C3 binden stärker als *. Zu lesen ist eine'solche • Deklaration von innen, also vom Namen aus na<:h außen. Die Speicherklasse eines Objektes macht Aussagen über die "Lebensdauer" dieses Objektes. (Existiert es nur während eines Funktionsaufrufes oder *» während des gesagten Programises?) Der Typ eir.es Cr^ektes sacht Aussagen über die Länge des Speicherplatzes und darüber wie das Garln enthaltene Bitaustsr zu interpretieren ist. (Wieviele 'Byte müssen für Werte, die das Objekt annehmen kann, reserviert werden? Soli FFFFH als -l oder als 65537 interpretiert werden?) I I I SPEICHERKLASSEN Es gibt fünf Speicherklassen: auto, register, static, extern, typedef. Außerhalb von Funktionen erklärte Objekte sind externe Objekte. Innerhalb von Funktionen erklärte Objekte sind interne Objekte. EXTERNE OBJEKTE Externe Objekte sind entweder im ganzen Programm oder nur in einem getrennt compiiierten Prograinrateil bekannt. Letzters wollen wir statisch nennen. Sie werden durch die Angabe der Speicherklasse static in der Deklaration erklärt. Fehlt die Angabe einer Speicherklasse in der Deklaration, so ist dieses Objekt im ganzen Programm bekannt. Wir wollen diese Objekte globale Objekte nennen. Tritt das Wort extern bei der Erklärung eines Objektes auf, so wollen wir von einer Definition und nicht von einer Deklaration reden, ca hier kein Objekt deklariert wird, sondern nur der Typ eines Objektes festgestellt wird und gesag-; wird, daß die Deklaration an anderer Stelle erfolgt. Speicherplatz für ein Objekt wird nur bei der Deklaration, nicht aber bei einer Definition angelegt. Definitioner, ein und desselben externen Objektes dürfen an verschiedenen Stellen eines Programmes auch innerhalb von Funktionen auf treten. Deklarationen müssen genau einmal geschehen. Jedes Objekt nu5 vor cec ersten Auftreten definiert sein. Wenn es in verschiedenen, getrennt corapilierten Programm*eilen benutzt wird, muß es in jedem davon definiert und in einen deklariert werden. Der Speicherplatz für ein externes Obj=rt wird bei der Deklaration =inaal angelegt und ist während des ganzen Prograrcialaufs vorhanden. INTERNE OBJEKTE Interne Objekte können temporär oder statisch sein. Statische Objekte erklärt man durch die .Angabe von static in der Deklaration. Sie werden genauso wie externe statische Objekte angelegt, in: t der Einschränkung, daß ihre Namen nur in der Funktion (bzw. in dem Block, in der ( d e m ) sie deklariert wurden bekannt sind. Auch ihr Speicherplatz ist während des gesamten Procraißüilaufs vorhanden. Temporäre Objekte werden durch die Angabe der Speicherklasse auto oder register in der Deklaration erklärt. Ihre Minien sind nur in der Funktion (bzw. in dem Block), in der (dem) sie deklariert wurden bekannt. Bei den bis jetzt vorgestellten Objekten ist der Speicherplatz während des gesamten Prograramlaufes vorhanden. Bei temporären Objekten ist das anders. Sobald die Funktion (bzw. der Block), in der (dem) sie deklariert wurden verlassen wird, existiert ihr Speicherplatz nicht mehr. Er wird bei jedea dieser Funktionsaufrufe (bzw. bei Eintritt in diesen Block) neu angelegt, register ist das Gleiche wie auto. Dem Compiler soll durch resister nur ein Hinweis ™* » «•* gegeben werden, den Zugriff auf ein häufig benutztes Objekt zu optimieren. Temporäre Objekte dürfen nur innerhalb von Funktionen erklärt werden! Falls bei der Deklaration keine Speicherklasse angegeben wird, wird bei einer Deklaration innerhalb von Punktionen üe Speicherklasse auto, bei einer Deklaration außerhalb von Funktionen ein globales Objekt angenommen. Sollen mehrere Dateien getrennt compiliert werden, die mit den gleichen Objekten arbeiten, sc müssen diese Objekte extern sein. Variablen als static • | j [ rn - C Cll Spracnbeschreibujiy zu deklarieren bietst sich an, wenn man sie nur von bestimmten Funktionen aus verändern und anderen Programmteilen keine Zugriff «Möglichkeit einräumen möchte. Falls eine Funktion rekursiv aufgerufen wird, sollte man mit der Deklaration von internen static Variablen in dieser Funktion vorsichtig sein, da bei jedem erneuten Aufruf der Funktion der alte Wert überschrieben wird. Vorzugsweise sollte man bei rekursivsn Funktionen Objekte der Speicherklasse auto verwenden. Mit typedef wird kein Speicherplatz ange.egt, sondern nur ein Name bestimmt, der später anstelle eines Typs (Schlüsselwortes) benutzt wird. An einem Beispiel sieht man am besten, was Typedef macht: Seispiel statt int IVAR; char NAME L 9 D ; ist nach typedef char NA«TyPC93; typedef int PRItt; ebenso zulässig PHin IVAR: NAHTYP NAME: Beispiel zu II DEKLARATIONEN Datei BSP: static VG; int VA: float V B C 8 3 ; extern int VF; FUNKTO int VC: extern int VH; static int VD; . auto char VE; ^ VG ist eine externe statische Variable, auf sie kann innerhalb der Datei BS? jede Funktion zugreifen. VA und VB sind externe Variablen, auf die auch von anderen Dateien aus zugegriffen werden kann. VF ist eine Variable, für die bereits in einer anderen Datei Speicherplatz angelegt wurde. In dieser anderen Datei ist VF eine externe Variable. Hier wird durch extern int nur auf die Existenz und den Typ von VF hingewiesen. Da bei VC keine Speicherklasse angegeben wurde, hat VC ebenso wie VE die Speicherklasse auto. Jedesn-al, wenn FUNKT aufgerufen wird, werden die Speicherplätze für , VC und VE erneut angelegt und beim Verlassen der Funktion FUNKT "vergessen". Der für VD anceleote Speicherplatz bleibt bestehen. — .*. u innerhalb der FunkHon TJNKT gibt bekannt, daß außerhalb der on-- FüNKT eine int Variable mit Namen VH existiert. (VH muß in einer • deklariert sein.) VC, VD und VE sind nur in FUNKT bekannt, VG, VH, und VF in der gesamten Quelldatei um. auf VA, VE, VH und VF können andere Dateien zugreifen. v;: c 13 112 TYP UND ARITHMETISCHE UnUANDLWGEN Man unterscheidet die folgenden arithmetischen Typen von Variablen: char Zeichen l Byte lang, wird bei Bearbeitung in int umgewandelt int Integer "(ganze) Zahl, 2 Byte lang, das höchste Bit wird als Vorzeichen interpretiert short genau so wie int long doppelt genaue int, 4 Byte lang • unsigned ganze Zahl, 2 Byte lang float Gleitkommazahl, 4 Byte lang, wird beim bearbeiten in double gewandeltdouble doppelt genaue float. 8 Byte lang long oder long int, unsigned oder unsigned int, long float oder double haben jeweils die gleiche Bedeutung. Falls bei einer Deklaration eine Speicher)lasse angegeben wurde, kann die Angabe eines Typs entfallen. Dann wird angenommen, der Typ sei int. (staue A entspricht static int A). ARITHMETISCHE UMUANDLUNGEN Viele Operatoren verursachen Umwandlungen. Beispiel int VARA; float VARB; VARA = VARA » VARB; Zunächst wird der Pert von VARB von flost nach double gewandelt, da mit doppelter Genauigkeit gerechnet wird. Der Uert aus VARA wird nach den unten angegebenen Regeln von int nach double gewandelt. Das Ergebnis ist voa Typ double. Da VARA vom Typ int i »t, wird das Ergebnis vom Typ double nach int gewandelt und dann VARA zugewiesen. Hierbei ist zu beachten, daß bei der Umwanilung nicht geprüft wird, ob die umzuwandelnde Zahl für .den neuen Typ zu groß oder zu klein ist. Liste der automatischen arithmetischen Umwandlung: - Jeder Operand vom Typ char wird nach int und jeder Operand vom Typ float wird nach double gewandelt. - Falls einer der Operanden vom Typ doub.'.e ist, wird der andere nach double gewandelt. Das Ergebnis ist ebenfalls vom Typ double. - Anderenfalls: Ist einer der beiden Operanden vom Typ long, so wird der andere ebenfalls nach long gewandelt. Das Ergebnis ist ebenfalls vom Typ long. - Anderenfalls: Ist einer der Operanden von Typ unsigned, wird auch der andere nach unsigned gewandelt. Das Ergebnis ist vom Typ unsignec. - Anderenfalls: Beide Operatoren müssen vom Typ int sein. Das Ergebnis ist - vom Typ int. KI - C 113 FELDES, POINTE3, STRUCT UMD UNION Ein Feld besteht aus Objekten gleichen Typ;;. Die Länge des Feldes, d.h. die Anzahl der in diesem Feld zusammengefaßten Objekte, wird in der Deklaration in eckigen Klammern hinter den Feldnamen gE schrieben. Speicherklasse Typ Feldname C Feldlänge ]; Beispiel int ZAHLEN C303 ; das Feld ZAHLEN besteht aus 30 Objekten vcm Typ int. Auf die einzelnen Objekte wird durch Feldname Centsprechender Index] zugegriffen. Wichtig: die Indizierung beginnt !>ei 0 und hört mit Feldlänge - l auf. Im. Beispiel ist das erste ObjeJct durch ZAHLEN C D ] , das zweite durch ZAHLEN C 1 3 , ..., das letzte durch ZAHLEN i!293 zu erreichen. Feldname alieine zeigt auf das erste Objekt des Feldes, im Beispiel: ZAHLEN ist dasselbe wie i ZAKLEN C O D . Man kann die einzelnen Feldelemente statt durch Feldname Cij ebenso durch «(Feldname + i) erreichen. im Beispiel: ZAHLEN Ci] = »(ZAHLEND i) / • Ebenfalls gleichbedeutend ist: ZA'HLEN - i und & ZAHLEN cu. Ein Pointer kann ähnlich wie ein Feldname behandelt werden. Der hauptsächliche Unterschied ist der, daß bei der Deklaration eines Pointers kein Speicherplatz für die Objekte, auf die der Pcinter zeigt, freigehalten wird, sondern nur eine "Variable" deklariert wir i, die eine Adresse enthalten kann. Deshalb muß einem Point er vor der Benutzung ein Wert zugewiesen werden. Falls man einen Pointer PZAHLEN erklärt ' j int * PZAHLEN; und ihm die Anfangsadresse des Feldes zuweist PZAHLEN = ZAHLEN; so kann man auch hier die einzelnen ObjeJcte ies Feldes gleichermaßen durch PZAHLENCi] oder »(PZAHLEN + i) erreicien, was gleichbedeutend mit ZAHLEN Ci] oder »(ZAHLEN + i) ist. Allgemein Jcasn jeder Feld und- Indexausdruci: durch einen Pointer + Offset ausgedrückt werden. Zu beachten ist dabei, daß ein Pointer eine Variable ein Feldname aber eine Konstante ist. Somit sind Ausdrücke wie PZAHLEN++ (meint das nächste Objekt des Feldes Zahlen) PZAHLEN += 29 (rae_nt das letzte Objekt) erlaubt, aber ZAHLEN = PZAHLEN oder ZAHLEN** unzul issig. Ein Feie! kan.~ keine Funktionen enthalten. Po int er dagegen können auch auf Funktionen zeigen. Beisiel int («fupoi)(); • •• fupoi = fu; (*fupoi)(); In der letzten Zeile wird die Funktion fu r=Jcursiv aufgerufen. Ein mehrdimensionales Feld wird als Feld von Feldern aufcefaßt —• ' deren Dimension um l Kleiner ist als die Dimension äes Feldes seUser. Beispiel int Q C 2 3 C 3 3 C 4 3 ; Q ist ein dreidimensionales Feld (2x3x4). Q besteht aus zwei zweidiiaensionalen Feldern, die wiederum bestehen je ais drei eindimensionalen Feldern, jedes der eindimensionalen Felder besteht ai.s 4 ganzzahligen Uerten. QCi3 ist zweidimensionales Feld QCi3Cj3 ist eindimensionales Feld ' Q C iK ]1 Ck3 • ist üert vom Typ int Beim linearen Durchlaufen des Feldes läuft der letzte Index am schnellstsn. d.h. im Beispiel würde auf das Feld Q der Eeihe nach so zugegriffen: QCOJC03CO], QC03C03C1], QC03C03C23, QC03C13C03. ... QC03 C23C03 . ... Q C 1 3 C 0 3 C03 , ... QC13C13C03, ... QC13C23C03, QC1JC23C13, QC13C23C23, QCOjCODCa]," QC03C13C33, QC03 [23 £33 , QC13C03C33 , QC13C13C33, QC13C23C33 —•u. G w STRUKTUREN Eine Struktur ist einem eindimensionalen Feld ähnlich. Im Gegensatz zu einem Feld können aber bei einer Struktur die Elemente verschiedenen Typ haben. Außerdem geschieht der Zugriff nic.it über einen Index sondern über einen Namen. Beispiel struct ADRESSE int POSTLZ; char ORTC203; char STRC183; int NR; iins Strukturäeklaration beginnt mit stri.ct, es folgt ein Name (hier: ADRESSE), der die Struktur benennt. Danacr. werden eingeschlossen in Klammern {} die Elemente definiert. Ein Ausdruck struct Strukturname kann nun <;enauso als Typ verwandt werden wie z.B. int oder char. Durch struct ADRESSE ( .... } CORNELIA ; hat man ein Objekt vom Typ Struktur ADRESSE erklärt. CORNELIA hat A Elemente und eine Länge von 42 Byte. CORNELIA.POSTLZ bezeichnet das erste Element von CORNELIA und kann genauso' verwandt werden wie eine Variable vom Typ int. CORNELIA.ORT ist ein Feld aus Zeichen, von denen CORNELIA. ORT [03 das erste ist. Besonderheit beim Zugriff über Pointer: Beispiel i • j ' j siruct ARTIKEL ( ! int NR; fioat PREIS; char BEZEICH L30]; int LAGER; > * EINKAUF; EINKAUF ist ein Pointer auf eine Struktur mit Namen ARTIKEL. Statt ("EINKAUF).PREIS ist es ebenso möglich EINKAUF -> PREIS zu schreiben (Pfeil = minus größer). Jedesmal ist das Elsoent PREIS der Struktur, auf ciie der Pointer EINKAUF zeigt/ gemeint. • Eine Struktur kann als Element auch sine weitere Struktur haben. Es ist möglich, daß eine Struktur einen Pointer auf*ein Objekt vom Typ der gerade definierten Struktur enthält. Dadur:h ist es möglich verkettete Listen zu erzeugen. Strukturen mit dsui gleichen Nasen und Funktionen sind als Elemente einer Struktur nicht zugelassen (wohl aber Pointer iarauf). • • M* - C C'17 Spracht/eschreibuiiy'"'' UNION Einer Stra)ctur ähnlich ist union. Bei etier Struktur liegen die Speicherplätze der einzelnen Elemente hinter ein. uider. Bei einer union hingegen befinden sich die einzelnen Elemente auf dem gleichen Speicherplatz. Die Länge einer union ist.also die Länge ihres längsten Elementes. Der Zugriff auf einzelne Elemente erfolgt genauso wie bei Strukturen. Beispiel union A (int l; char *C; float F; } UVAR; • • • »• switch (TYPE) case l: UVAH.I = 4] break; case 2: UVAR.F = 4.004; break; default: UVAR.C = "FEHLER"; j •• •• l *f o^j.ac. r iDes-:nr5i •• 114 INITIALISIERUNG Bei der Deklaration ist es möglich, den deklarierten Objekten einen Anfangswert zuzuweisen. z.B. int I = 8; allgemein sieht eine Initialisierung so aus: zu initialisierendes Objekt = AUSDRUCK = { INITIALISIKRUNGSLISTE } = ( INITIALISIIiRUNGSLISTE , } wobei die INITIALISIEKUNGSLISTE so aussieht: AUSDRUCK INITIALISIERUNGSLISTE, INITIALISIERUNGSLISTE ( INITIALISIERUNGSLISTE } Bei der Initialisierung von statischen und /on externen Objekten dürfen die Ausdrücke nur konstante Ausdrücke sein bzw. Adressen von zuvor deklarierten Obiekten. Zu diesen Adressen darf ein konstanter Ausdruck addiert bzw.von diesen Adressen darf ein konstanter Ausdruck subtrahiert werden. Variablen der Speicherklasse auto können mit beliebigen Ausdrücken (konstanten Ausdrücken, Aufrufen von bereits deklariert sn Funktionen oder Variablen) initialisiert werden. Sie werden jedesmal bei Eintritt in den Block, in dem sie deklariert wurden, neu vorbesetzt. Alle anderen Objekte werden nur einmal bei Programmbeginn initialisiert. Falls Objekte nicht vorbesetzt werden, enthalten sie irgendeinen Anfangswert. Felder und Strukturen der Speicherklasse auio und union dürfen nicht vorbesetzt werden! Wenn das vorzubesetzende Objekt ein Feld cder eine Struktur ist, sind die Anfangswerte in (} Klammern eingeschlossen. Falls weniger Anfangswerte als • Feldelemente angegeben werden, werden die restlichen Feldelemente mit 0 v erbe setz t. üie man durch besondere Anwendung der KLammerung {} bestimmte Teile eines Feldes vorbesetzen kann, sieht man an den folgenden Beispielen. Beispiele a.) " statte Int J C 5 3 C 4 3 = { {1,2,3,4} , (11,12,13,14) }; J ist ein zweidimensicnales Feld, das aus 5 Elementen besteht. Jedes ELeraent ist ein eindimensionales Feld, das ais 4 Elementen besteht. Jedes dieser Elemente ist vom Typ int. Die beiden ersten der fünf Elemente, aus denen J besteht, sind mit den angegeben Uerten vorbesetzt. Der Rest wird mit 0 vcrbesetzt. d.h. J C C 3 C 0 3 = l, J C 0 3 C 1 3 = 2 , JC03 C23 = 3, JC03 C33 = 4, J C 1 3 L 0 3 = 11, J C 1 3 C 1 ] = 12, J C 1 3 C 2 3 = 13, J C 1 3 C 3 3 = 14, JC2JÜO] = 0, JC33C03 = J C 4 3 C03 = 0, 0, ... [ l JC43C33 = 0 dieselbe Vorbesetzung erreicht maji 'auch durch: static int J C 5 3 C 4 3 = ( 1, 2, 3, 4, 11, 12, 13, 14 }; i . ii i. aber durch b.) static int J[53[43 = ( (1), (2), (3), (4), {9} }; wird von jedem Element, aus dem J besteht, das erste Element mit den angegebenen Werten vorbesetzt und der Rest mit 0. also: J[03 [03 s 1, J [ 0 3 [ 1 3 = o, JC13COD = 2, J[23 [03 — 3, J[33 [03 = 4 , 9, J[43[Q3 J[13 [13 = J[23[13 — J[33[13 r J[43[13 • o, o, o, o, Allgemein gilt, daß die Klammemng so ausgewertet wird: Wenn die in (} eingeschlossenen Anfangswerte noch weiter mit Hilfe von Klammern {> gruppiert sind, so wird mit den in weiteren Klammern eingeschlossenen, durch Kommata getrennten Anfangswerten zunächst das entsprechende Element des Feldes mit den in Klammern zusammengefaßten Werter vcrbesetzt. Falls das Element aus mehr Elementen besteht als Werte angegeben wurden, werden die restlichen Elemente des Elementes mit 0 vorbesstzt. Anschließend wird mit den nächsten in Klammern eingeschlossenen Werten und dem nächsten Feldelement die Initialisierung fortgesetzt. ( wie in Beispiel b.) ) Falls die in (} Klammern eingeschlossenen Ai.fangswerte nicht durch weitere Klammem zusammengefaßt werden, werden der Reihe nach die terminalen Elemente des Feldes mit diesen Werten vorbesetzt. ( wie in Beispiel a.) ) Allgemein gilt, das keine "überschüsssigen" Werte angegeben werden dürfen. Ein Feld vom Typ char kann durch einen Striig vorbesetzt werden. Beispiel char~W[3 = "COMPILER"; Beispiel Die Struktur CORNELIA aus 113 könnte so initialisiert werden: struct ADRESSE CORNELIA* (4443/'SchuettorfY'Nordhor,6}; oder auch {{4443},rSchuettorf" },C'Nordhof }.{€}}. Falls bei einer Felddeklaration mit Initialisierung die Angabe der Feldlänge unterbleibt, wird sin Feld definiert, das genauso viele Elenente hat, wie in der Initialisierung Werte vorhanden sind. Beispiel static int K[3 = ( 3, 6, "9 }; K ist ein Feld mit drei Elementen vom Typ int. t i 20- " III AUSDRUCKE III l PEIHÄRE AUSDRUCKE Primäre Ausdrücke sind: • a Name, der nach den Konventionen in II de.clariert wurde z.B.: nach int VA; VA • i . j b Konstante z.B.: G, 'S', '0' c String ^i» • C * • X ±~S\ A • d (Ausdruck) " S * ~ • D,, X( R4-G.} w f - o / , il 'lj' n /\ e Primärer Ausdruck [Ausdruck] z.B.: nach char PC10]; PC2+4J (Fe.delement) f PriEärsr Ausdruck (Ausdruckliste) Ausdruc cliste kann entfallen z.B.: MAX(A,3) (Funktionsaufruf) g Primärer Lvalue.Name z.B.: CORNELIA.STR ,- h Primärer Ausdruck -> Name z.B.: EINKAUFSPREIS (Element einer Stuktur oder Union) Eine Ausdruckliste kann aus einem oder melireren Ausdrücken bestehen, die • durch Kommata getrennt sind. Ein Lvalue ist ein Ausdruck, der sich auf ein Objekt bezieht. Z.B. der Name einer Variablen oder ein Ausdruck der Form "Pointer. Faustregel: Ein Lvalue ist etwas, das links von einem Gleichheitszeichen siehen kann, dem man also etwas zuweisen kann. Die Zahl 3 ist kein Lvalue, sie hat einen festen Wert, man kann ihr nichts zuweisen. Unbekannte Namen, denen eine Klammer ( folgt, werden automatisch als Namen einer int Funktionen definiert. • / i I I I 2 AUSDRUCKE K I T OPERATOREN a Monodische Operatoren tfonadische Operatorsn sind solche, die auf nur ein Element wirken. Die hier aufgelisteten Operatoren haben alle die g. eiche Priorität. Die Abarbeitung erfolgt von rechts nach linJcs. (d.h. bei - <* A; wird zuerst " und dann - ausgeführt) ! AUSDRUCK (logisches Nicht) Das Ergebnis von ! AUSDRUCK ist l, falls AUSDRUCK = 0 ist, sonst 0. Der Typ ist int. ~ AUSDRUCK (Einerkomplement) AUSDRUCK muß ganzzahlig sein und wird Bitweise komplementiert ~ FFFS = 0006 - AUSDRUCK (Minus) AUSDRUCK wird negiert. — LVALUE -H- LVALUE LVALUE — LVALUE ++ VA = -3: ! LVALUE wird um l erhöht, bzw. um l erniedrigt. Welche Auswirkungen es hat, wenn ++ bzw. — vor oder nazh LVALUE steht, sieht man an foloenäem BeiSDiel: X = 5; Y = — X; erst wird der Wert von X um l erniedrigt und dann Y zugewiesen. Uert von. X = 4 und Wert vcn Y = 4. X = 5; Y = X — ; erst wird Y der Wert vcn X zugewiesen und dann wird X um l erniedrigt. Uert von X = 4 und Uert von Y = 5. aLVALUE & LVALUE ist Pointer auf LVALUE d.h. & LVALUE ist die Adresse von LVALUE z.B. int A; dann ist &A ein Pointer auf die int Variable A. » AUSDRUCK AUSDRUCK muß ein Pointer sein. » AUSDRUCK bezeichnet das Objekt, ,iuf das der Pcinter AUSDRUCK zeigt, und ist Lvalue. «* z.B. int 3; *. * & S = 5; entspricht: B = 5; char FE1Q]; F C 4 ] entspricht * (F + 4) sizeof AUSDRUCK sizeof gibt die Länge von AUSDRUCK in Byte an und ist eine Konstante vom Typ int. z.B. int A; Der Uert von sizeof A beträijt 2.* double F C 4 3 ; Der Wert von sizeof F beträgt 32. sizeof (TYFMAnE) sizeof gibt die Länge vcn TYP in Byte au und ist eine Konstante VOID Typ int. z.B. sizeof (struct ZIC(int »\; char 3 C 7 ] ; } ) hat den Uert 9. ( einmal 2 Byte und 7 mal l Byte) (TYPNAHE) AUSDRUCK wird CAST (Typumwandling) genannt. z.B.: int VA; sin((float) VA); sin wird aufgerufen mit dein nach float gewandelten Uert von VA \ TYPNAME hat folgende Form: TypangeLbe abstrakter Deklarator pangabe char, int. Icng, unsigned, float, double, Uni^naugabe. StruJcturajigabe, mittels typedef geschaffener Datentyp abstra)cter Deklarator nichts (abstrakter DeJclarator) ' «abstra>cter Deklarator abstrakter Deklarator abstrakter Deklarator [konstanter Ausdrick(opt)] Beispiels für TYPfoAME: long»() int(»)C4] Funktion, die Pointer auf long zurückgibt Pcinter auf ein Feld vor. 4 integers . ! j i b Dysdische Operatoren Dyadische Operatoren sind solche, die auf zwei Elemente wirken. Die folgenden drei Operatoren nennt man miltipliJcative Operatoren. Sie besitzen die gleiche Priorität. Ihre Abarbeitung erfolgt von links nach rechts. (A/B»C zuerst wird A/B ermittelt uni dann das Ergebnis mit C multipliziert.) AUSDRUCK • AUSDRUCK Multiplikation AUSDRUCK / AUSDRUCK Division AUSDRUCK Z AUSDRUCK Moduio (z.B. 5 * 3 = 2 Rest bei Division) Die beiden folgenden Operatoren sind additive Operatoren. Sie haben die gleiche Priorität. Ihre Abarbeitung erfolgt von links nach rechts. AUSDRUCK + AUSDRUCK Summe AUSDRUCK - AUSDRUCK Differenz Pcinter werden bei der Addition und Subtrakt.on gesondert behandelt. Wird zu einen Pointer eine ganze Zahl addiert öde: von einein Pointer eine ganze Zahl subtrahiert, so hat der gesamte Ausdjruck den gleichen Typ wie der ., Pointer. Die ganze Zahl wird in beiden Fällen so skaliert, daß der Pointer ua soviele Element weiter zeigt, wie die ganze Zahl angibt. P p i er»-: a]* •W W ^ _ k* ,_•_ O. « long"?CS3, «POI; POl = ?; . ?OI -*- A zeigt dann auf das A. Element im Feld P, also wurden 16 Byts zur Adresse in POI addiert. also (Pointer + 1) zeigt nicht auf eine Stelle die ein Byte höher liegt, sondern auf das nächste Objekt des Feldes. Falls zwei Pointer POI l und POI 2 auf Objekte vom gleichen Typ zeigen, gibt POI l - POI2 die Anzahl der Objekte (gleichen Typs) an, die zwischen den beiden Pointern stehen. Die folgenden zwei• Operatoren heißen shift (schiebe) Operatoren. Sie haben die gleiche Priorität. Ihre Abarbeitung erfolgt von links nach rechts. AUSDRUCKl » AUSDRUCK2 AUSDRUCK1 « AUSDRUCK2 Der Wert der beiden beteiligten Ausdrucke muß ganzzahlig sein. AUSDRUCK 2 wird in int gewandelt. Das Ergebnis ist vom gleichen Typ uie AUSDRUCK l. Beispiel: 9 « 3 = 72 (0000 0000 0000 1001 « 3) = (0000 iDOOO 0100 1000) Beim nach links Shiften wird 0 nachgerückt. Beim nach rechts Shiften wird, falls das Vorzeichen gesetzt ist, l sonst 0 nachgerückt. Beim sruften eines Ausdrucks vom Typ unsignei wird in beiden Fällen eine 0 nacherückt. Die folgenden vier Operatoren nennt man \ergleichsoperatoren. Sie haben die gleiche Priorität. Ihre Abarbeitung erfolgt von links nach rechts. AUSDRUCK < AUSDRUCK AUSDRUCK > AUSDRUCK AUSDRUCK <= AUSDRUCK AUSDRUCK >= AUSDRUCK Der Uert eines solchen Vergleiches ist 0, falls der Vergleich falsch ist, l sonst. Der Typ des Ergebnisses ist int. Beispiel: Der Uert von 4 > 4 ist 0 '. . Der Uert von 4M > 4 ist l Der Uert von 3 < 2 < 5 ist l !!! ( Uert von 3 < 2 ist 0, Uert von 0 < 5 Ist l ) Auch Vergleiche zwischen Pointern sind möglich. Die beiden folgenden Cperatoren heilten Gleic.iheitsoperatoren. AUSDRUCK == AUSDRUCK AUSDRUCK != AUSDRUCK Falls beide Ausdrücke gleich sind, ha" AUSDRUCK == AUSDRUCK den Uert l und AUSDRUCK != AUSDRUCK der Uert 0. Das Ergebnis hat den Typ int. Beispiel: 5 != 5 hat den Uert 0 10 > ' 8 == -l < 2 hat den Uert l Es folgen 3 bitweise Operatoren, die nach absteigender Priorität aufgelistet sind. AUSDRUCK £ AUSDRUCK Bitweises UND Die beteiligten Ausdrücke müssen ganzzihlige Uerte haben. Die Abarbeitung erfolgt von links nach rechts. ' Beispiel: 13 & 7 = 5 ' (0000 0000 0000 1101) & (0000 0000 0000 0111) = (0000 0000 0000 0101) AUSDRUCK ~ AUSDRUCK Bitweises exklusives ODER Die beteiligten Ausdrücke müssen ganzzahlige Uerte haben. Beispiel: 13 * 7 = 10 (0000 0000 0000 1101) ~ (0000 0000 0000 0111) = (0000 0000 0000 1010) AUSDRUCK | AUSDRUCK Bitweises ODER Die beteiligten Ausdrücke müssen ganzzahige Uerte haben. Beispiel: 13 | 7 = 15 (0000 0000 0000 1101) 0000 1111) | (0000 0003 0000 0111) , r t i ' = (0000 0000 j l Die beiden folgenden logischen Operatoren siid ebenfalls nach absteigender Priorität aufgeführt. Beide werden von links n ich rechts abgearbeitet. AUSDRUCK &a AUSDRUCK logisches UND AUSDRUCK l && AUSDRUCK2 hat den Uert l, falls AUSDRUCK l und AUSDHUCK2 beide ungleich 0 sind. Falls AJSDRUCKi gleich 0 ist, wird AUSDRUCK2 nicht mehr ermittelt, sondern gleich der Uert 0 zurückgeliefert. Beispiel: Bei A &Sc PUTCHAR(A) wird ?UTCHAR(A; nur aufgerufen, wenn A ungleich 0 ist. v| T AUSDRUCK | j AUSDRUCK logisches ODER AUSDRUCK! M AUSDRUCK2 hat den Uert l, falls wenigstens einer der beiden Ausdrücke AUSDRUCK!, AUSDRICK2 ungleich 0 ist. Sonst 0. Falls AUSDRUCK l ungleich 0 ist. wird VJSDRUCK2 nicht mehr ermittelt und der Uert l zurückgeliefert. In beiden Fällen ( && und | | ) können cLe Ausdrücke verschiedenen Typ : hai>en. Das Ergebnis hat den Typ int. AUSDRUCK ? AUSDRUCK : AUSDRUCK beding-:er Operator Der Uert von AUSDRÜCK ? AUSDRUCK l : AUSDRUCK2 ist AUSDRUCK l, falls AUSDRUCK ungleich 0 ist, sonst AUSDRUCK2 Beispiel: A = B > C ? C : B; A wird das Minimum von C und B zugewiesen. A = A < 0 ? -A : A falls A < 0 ist, wird A negiert. Falls keiner der beiden Ausdrücke AUSDRUCK l, AUSDRUCK2 ein Fointer ist, wird nach den Regeln aus Kapitel 112 zu dein gemeinsamen Typ gewandelt. Uenn einer der Ausdrucks AUSDRUCK!, AUSDRUCK2 ein Pointer ist, muß der andere ein Pointer vom gleichen Typ sein oder die Konstante 0. Zuweisungsoperatoren: Beispiele: LVALUE = AUSDRUCK A = B ; Wert vor A = B ist 3 LVALUE += AUSDRUCK A += F; entspricht A = A + F; LVALUE -= AUSDRUCK A -= 9; entspricht A = A - LVALUE * = AUSDRUCK A * = 3+D; ent;;pricht A = A * < 3+D ) ; LVALUE / = AUSDRUCK A / = G ( ) ; ent'ipricht A = A / G ( ) ; LVALUE *= AUSDRUCK 9; = 4-H; entspricht A = A * ( 4 - H ) ; LVALUE » = AUSDRUCK A »= 6; entspricht A = A » 6; LVALUE « = AUSDRUCK A «= 3; entspricht A = A « 3; LVALUE A 5c= AUSDRUCK &= 2; entspricht A = A & 2; t LVALUE ~ = AUSDRUCK . LVALUE = AUSDRUCK ' A ~ = B ; entspr.cht A = A Ä B; = C ; entspr.cht A = A | C ; D er Operator mit der niedrigsten Priorität ist der Komma Operator. Seine Abarbeitung erfolgt von links nach rechts. AüSDRUCKl , AUSDRUCK2 Zunächst wird der Wert des Ausdrucks AUSDRUCK l ermittelt, anschließend der von AUSDRUCK 2. Der Uert und Typ von AUSDRUCK l ,AUSDRUCK2 ist der Uert und Typ von AUSCRUCK2. Falls der Kcmmaoperator innerhalb einer LLrte von FunJctionsargumenten oder als Feldindex auftritt, also an Stellen, an denen das Komma bereits eine andere Bedeutung hat, müssen Klammern gesetzt werden. • Beispiel for ( i=j=0 ; ] <= i | | (3=0, ++i < max) ; -H-J ) JccDisrt das untere Dreieck einschließlich der Diagonalen von Matrix 112 nach Ml". Zusammenfassend eine Tabelle mit allen Operatoren, nach absteigender Prio rität geordnet. Operatoren mit gleicher Priorität stehen in einer Zeile. o n . -> » » & / X ! , -v -H- — sizeof (typname) < > < = > = l == ! != & 5 l »= /= J= »= «= &= I I I 3 KONSTANTE AUSDRUCKE Konstante Ausdrücke sind Ausdrücke, deren Uert eine Konstante ist. An bestimmten Stellen müssen in einem C Programm konstante Ausdrücke stehen: a bei case C: muß C ein solcher Ausdruck sein. b bei der Angabe von Feldlängen z.B. chiir NAME CK3, muß die Feldlänge (im Beispiel K) ein konstanter Ausdruck :;ein. c nach #if muß ein konstanter Ausdruck stehen d bei der Initialisierung z.B. bei int A = F muß F ein konstanter Ausdruck sein. In den Fällen a, b und c sind die folgenden konstanten Ausdrücke erlaubt: ganzzahlige Konstanten vom Typ int ZeichenkonstantEn sizeof Ausdrücke Die genannten konstanten Ausdrücke dürfen loch mit den folgenden Operatoren verknüpft sein: : den monadischen Operatoren - ** den dyaoischen Operatoren + - » / * & | ~ « » und dem bedingten Operator ? : i Im Fall d ist außer den für a, b und c angegebenen konstanten Ausdrucken noch Folgendes zulässig: Der monadische Operator & verknüpft mit einem schon deklarierten statischen oder externen Objekt, also dessen Airesse. Zu dieser Adresse darf eine Konstante addiert bzw. von ihr subtrahiert werden. Beispiel z.B. nach static float FF; ist &FF + 4 5 bei der Initialisierung erlaubt (aus + 45 wird, da FF vom Typ float ist + 4 » 45) Zusätzlich gilt bei HI - C: In den Fällen a und d sind ebenfalls Konstanten vom Typ long und double erlaubt. tt* i ..' '•. ' l IV . ANWEISUNGEN IVl if - e i s e A n w e i s u n g Diese bedingte Anweisung sieht allgemein so aus: if ( AUSDRUCK ) ANWEISUNGl eise ANWEISUNG2 Der Teil eise ANWEISUNG2 kann auch entfallen. Zunächst wird der Uert von AUSDRUCK ermittelt. Falls dieser Uert ungleich 0 ist, wird die Anweisung ANWEISUNG l ausgeführt. Falls der Wert von AUSDRUCK 0 ist, wird ANWEISUNG l übersprungen und ANWEISUNG 2 ausgeführt oder falls eise "**} ANWEISUNG 2 nicht vorhanden ist, wird nur ANWEISUNG l ignoriert und hinter ANWEISUNG l der Frogrammablauf fortgesetzt. Beispiel ( C ) ?RINTF("NULL" ) ; eise EINS wird ausgedruckt. PRINTF ( " E I N S " ) ; if ( VA == VB ) VC = VA + V B ; eise wenn VA gleich VB ist, wird VC der Wert von VA+V3 zugewiesen wenn VA ungleich VB ist,wird VC der Wert 100 zugewiesen if zuerst wird X ier Wert von Y zugewiesen, we.in Y und damit X gleich 0 ist. wird Z 0 zugewiesen. Sons-; 2 » X. vc = 100; (X = Y) z = 2 » x; eise Z = 0; Die if - eise Anweisung kann auch geschachtelt werden. Beispiel if ( ~A + B ) r if ( A + B > 0 ) C = A -K B: £is= C = - ( A + B ); eise C r 100; Eei geschachtelten if - eise Anweisungen ist zu beachten, daß sich eise stets auf das letzte if, auf das noch kein =lse gefolgt ist, bezieht. Nur durch Klammerung { } kann man erreichen, da.3 sich jedes eise auch auf das gewünschte if bezieht. Bsispiel zwischen a.) if ( X + Y ) if ( X + Y > 0 Z = X + Y; eise Z = 100; und b.) if ( X + Y ) C if ( X + Y > 0 z = x + Y; eise Z = 100; ist ein großer Unterschied. In a.) wird das eise dem innersten if zuaeordnet. falls X+Y > 0 ist, wird Z der Uert von X*-Y zugewiesen falls X+Y = 0 ist, wird Z nicht verändert. falls X+Y < 0 ist, wird Z der Uert 100 zugewiesen. In bJ wird das eise dea äußeren if zugeordnet. falls X+Y > 0 ist, wird Z der Uert von X+Y zugewiesen falls X+Y = 0 ist, wird Z der Uert 100 zugewiesen falls X+Y < 0 ist, wird Z nicht verändert. *s Eine weitere mögliche Schachtelung ist: if (AUSDRUCK 1) ANUEISUNG1 elss if (AU5DRUCK2) ANWEISUNG2 eise if (AU5DHUCK3) ANWEISUNG3 • • • eise ANWEISUNG! Durch diese Art der Schachtelung, hat man die Höglichkeit mehr als nur 2 Fälle zu unterscheiden, da folgenden Eeispi=l 4) HI - C C 30 Spracnüeiciii-riLu..-.- Beispiel if ( ! C ) C = 100; eise if ( C > 100) C »= 2; . eise if ( C <= 100 && C > 0 ) C •= 3; eise c = -c; Die vier Fälle C< 0, C = 0, . 0 < C < = 1 0 0 , C> 100 werden unterschieden. IV2 switch A n w e i s u n g Allgemein sieht die switch Anweisung so aus: switch (AUSDRUCK) case konstanter AUSDRUCK l: ANUEISUNGS r OLGEl case konstanter AUSDRUCK2: ANUEISUNGS rOLGE2 default: ANUEISUNGSFCLGEi default ANUEISUNGSFOLGEi kann entfallen. Ausdruck muß bei MI - C nicht vom Typ int sein. Die konstanten Ausdrücke AUSDRUCK l, AUSDRUCK 2, ... müssen alle verschieden sein, und gleichen Typ wie AUSDRUCK haben! (zulässige Ausdrücke siehe III3) Bei. der switch Anweisung wird zunächst der Wert von AUSDRUCK ermittelt. Er wird mit den nach jedem case folgenden konstanten Ausdruck verglichen. Sobald eine Übereinstimmung festgestellt wir i, wird mit der Anweisung sfolge, die dem case, bei dem die Übereinstimmung festgestellt wurde, folgt, fortgefahren und die switch Anweisung nach brs-ak verlassen. Falls kein break gesetzt ist, werden die Anweisungen nach jedem der folgenden case ebenfalls ausgeführt (bis break oder return gefunden wird). Falls mit keinem case Übereinstimmung festgestellt wurde, wird di?> Anweisung nach default ausgeführt oder falls kein default vorhanden ist, wird das Programm nach der Endeklamraer } von switch fortgesetzt. Beispiel MAINt) ( int i; I = GCHO; switch (I) { case r: FUNKIO; break; case '2' case '3' case '4' default: FUNK20; FUNK3O; FUNK40; break; PRINTF ("FALSCHE EINCÄBE") Falls das Eingabezeichen eine l ist, wird lie FurJction FUNK l ausgeführt und die switch Anweisung verlassen. Falls das Eingabezeichen eine 2 ist, werden die Funktionen FUNK2, FUNKS und FUNK4 ausgeführt und dann die switch Anweisung verlassen. Falls das Eingibezeichen eine 3 ist, werden FUNK2 und FUNK4 ausgeführt und die switch Anweisung verlassen und falls das Eingabezeichen eine 4 ist, wird nur FJNK4 ausgeführt und dann die switch Anweisung verlassen. Falls das Eingabszeichen ungleich l, 2, 3 oder 4 ist, wird FALSCHE EINGABE ausgedruckt. IV3 w h i 1s Anweisuna Aiiaemein sieht eine while Anweisung so aus: wnüe (AUSDRUCK) ANWEISUNG i Zunächst wird der Wert von AUSDRUCK erm:.ttelt. Falls dieser Wert ungleich 0 ist, wird ANWEISUNG ausgeführt. ANWEISUNG wird so oft ausgeführt, bis AUSDRUCK gleich 0 ist, dann wird hinter ANWEISUNG fortgefahren. i Beispiel while ( ! ) ( . . . } ist Endlosschleife (kann nur mit break, return oder goto verlassen werden) T A r-. = l' o., • ; while ( A <= 25 ) B = A * A; PEINTF ("\R\NDAS QUADRAT VON ZD IST ::D M ,A, B): Die Qüadratzahlen von l bis 25 werden ausgedruckt. / Kit break (ebenso mit goto bzw. retum) kanji eins while Anweisung vorzeitig verlassen werden. Beispiel A = \; while ( A <= 25 ) B = A » A; if ( B > 400) break*. PRINTF ("\R\NDAS QUADRAT VON XD IST XI) '^A, B); -A: Nur noch die Quadratzahlsa von l bis 20 wenien ausgedruckt. r: II i l IV4 f o r A n w e i s u n g Die for Anweisung hat die Form: for (AUSDRUCKl; AUSDRUCK2; AUSDRUCKS) ANWEISUNG Die for Anweisung ist äquivalent zu: AUSDRUCKl; while (AUSDRUCK2) ANUEISUNG AUSDRUCKS; } In der for Anweisung können die Ausdrücke AUSDRUCKl ____ entfallen, aber die Semikolon müssen hingeschrieben werden! Falls der Test (= AUSDRUCK2) fehlt, wird angenommen er sei ungleich 0. m t for (AUSDRUCK l ;; AUSDRUCKS) erhält man eine Endlosschleife. Das Fehlen der Ausdrücke AUSDRUCKl und AUSDRUCKS hat keine Folgen. Eine for Anweisung kaim ebenfalls durch break, goto oder retora vorzeitig beendet werben. Beispiel for (I = 0 ; I < 10 ; -H-I) FELCI] = 9; die ersten 10 Elemente von FEL werden mit 9 besetzt dss Gleiche erreicht man auch durch: I = 0; for ( ; I < 10 ; ) FELC I-H- ] = 9: IV5 do - w h i l e A n w e i s e n a Allgemein hat die do - while Anweisung die folgende .Form: do ANWEISUNG while (AUSDRUCK); Zunächst wird ANWEISUNG ausgeführt, dan.i wird ermittelt, ob AUSDRUCK ungleich 0 ist. Falls AUSDRUCK ungleich 0 ist, wird wieder ANWEISUNG ausgeführt und wieder ermittelt, ob AUSDRUCK gleich 0 ist. usw. Falls AUSDRUCK gleich 0 ist, ist die Schleife Beendet und das Programm wird hinter AUSDRUCK fortaesetzt. .Beispiel l = o; do ( J = I » I * i; (" . ?HINTF("\N\RriOD hoch 3 ist tD ",!, J) while (I < 10) 0 hoch 3 bis 3 hoch 3 wird berechnet und eusgecnic)ct. Die do - while Anweisung kann durch beendet werden. return, goto oder break vorzeitig •i II IVG b r e a k A n w e i s u n c Hit break können die for, do - while, switcr und while Anweisungen vorzeitig abgebrochen werden. Das Programm wird hinter der for, do - while, switch oder while Anweisung fortgesetzt. IV7 c o n t i n u e A n w e i s u n g Die continue Anweisung bewirkt, das innerhalb von while, do - while und for Schleifen ans Schleifenende gesprungen wird. Beispiel while ( A >= 100 ) 3 += 100; if ( B < 1000 ) continue; FELDCI-H-] -= B; A -= 10; ' _ } • ralls A) = 100 ist, wird B solange wie B ( I O O C ) ist, um 100 erhöht und der Schleifenrest übersprungen. Erst, wenn 8> = 10C»0 ist, wird auch der Rest der Schleife abgearbeitet, bis die Bedingung A) = 1CO nicht mehr erfüllt ist. Allgemein ist die Anweisung äquivalent zu goto WEITER: continue bei den verschiedenen while ( . . . ) . ( do ( fcr(..;..;..) ( WEITER: > WEITER: ; ) WEITER: > ; while (...); Schleifen IVS r e t u r n A n w e i s u n c j Die allgemeine Form der return Anweisung is". eine der beiden folgenden: return; return AUSDRUCK: la ersten Fall ist der zurückgegebene Uert nicht definiert, im zweiten Fall wird der Uert von Ausdruck zurückgegeben. Mit return wird eine aufgerufene Funktion verlassen und zur aufrufenden Funktion zurückgekehrt. Eine Funktion, die .cein return enthält, wird bis zu ihrer EndsJclammer } abgearbeitet und dann «nitomatisch (ohne einen Uert zurückzuaeben) verlassen. Beisiel int A I , A2 A3; A I = HAX2(A2,A3); a. c A! a* O, int C; c = A > B ? A : B; r=turn C «= 2; lii ,i v i t* MI _ r C 37 Sprachbeschreibuim v.-. -&"•*. IV9 label Anweisung Allgemeine Form der label Anweisung: MÄHE: NAHE ist ein Name nach den Konventionen ii I I . NAHE: darf nur vor einer Anweisung stehen. Gebraucht werden label Anweisungen zur Erstellung von Sprungzielen für goto Anweisungen, die in di?r gleichen Funktion stehen müssen. IV10 o o t o A n w e i s u n g Die goto Anweisung hat die allgemeine Form: goto NAHE; X NAME muß eine Sprungmarke sein (siehe lai>el Anweisung), die in der gleichen Funktion wie goto steht, goto NAHE bewirkt einen Sprung von der goto Anweisung zu der Anweisung, die hinter der Marke NAME steht. Man kann aus Schleifen oder Blöcken heraus-bzw. in-sie hineinspringen. Wenn in Blöcke hineingesprungen wird, enthalten alle dort definierten temporären Variablen einen beliebigen Wert. Die goto Anweisung sollte mit Vorsicht verwandt werden, da bei hemmungslosem Gebrauch von goto ein Programm unüix-rsichtlich wird und nur schwer oder car nicht zu warten ist. Beispiel Falls man verschachtelte Schleifen verlassen will, ist es mit break nur möglich, die innerste Schleife zu verlassen. while ( . . . ) while ( . . . ) ( if ( EINGABEFEHLER ) goto FEHLEING; FEHLEING: r £*! *! IV11 L e e r e A n w e i s u n o Sie hat die Fora: Beispiel whiie ( I-H- < 30 ) ; I wird solange um l erhöht, bis I >= 30 ist, IV12 B l o c k e n w e i s u n G Überall dort, wo eine der obigen Anweisunger stehen kann, kann auch sine in ( ... } eingeschlossene Folge von Anweisungen stehen. Vor die erste Anweisung können Deklarationen gesetzt werden. Die deklarierten ObjeJcte haben nur innerhalb des Blockes ihre Gültigkeit. IV13 A u s d r u c k - A n w e i s u n g Ein Ausdruck gefolgt von einem Semikolon ist eine Ausdruck - Anweisung. IID Normaifäll ist öies ein Funktionsaufruf oder =ine Zuweisung. r: r. i, £. l V . EXTERNE DEFINITIONEN extern = außerhalb von Funktionen Ein C Programm besteht aus einer Folge von externen' Definitionen, genauer von Definitionen von externen Objekten, d:.e hier in Funktionen und andere ObjeJcte, Daten genannt, eingeteilt werden seilen. Extern definierte Daten und Funktionen können beliebigen Typ ha£en. Sie müssen aber die SpeicherJdasse extern oder static haJben. Extern definierte Daten und Funktionen sind bis zun Dateiende bekannt. V I EXTEHNE DATENDEFINITIONEN Eine externe Dctendefinition ist eine DefcLiration siehe Abschnitt II. Die Speicherklasse einer solchen DeJdaration darf nur extern oder static sein. l E l I Bl l fi w,-*w V2 EXTERNE FUNKTIONSDEFINITIONEN Die allgemeine Form einer Funktionsdefinition sieht-so aus: Speicherklasse Typ Funktionsname (evtl. °arameterliste) Parameterdeklaration (falls Paramete.r vorhanden) FunJctionsJcörper = Folge von Deklar itionen lokaler Variablen gefolgt von Anweisungen Beispiel: long MOD2(X,Y> iong X, Y; Icng Z; Z = ( X > Y ) ? (X) X (Y) : (Y) 2 (X) ; rsturn 2* Z ; long vor HOD2(X,Y) gibt an, daß die Funktion HOD2(X,Y) einen Wert vom Typ long zurückliefert. hier: 2« Z Falls keis Tv• AD anaeaeben wird,' wird iinme:: anaenommen, daß die Funktion •*_ ^ ' . einen Itert VOE Typ int zurücklief ert. AiiGe:: bei Funktionen, die Werte vom Typ int zurücklief ern, muß vor den ersten Funktionsaufruf die Funktionsdefiniticn erfolgen. Falsch: Richtig: Richtig: MAINO long »HFUNKO extern long *nFUNK(); (.. X= - M F U N K O ; } ( ... } KAINC) T v long *MFL NK() i iAIN() {.. X = »MFUNK»;} ' {.. X = »WFJNKO;} Uichtig! Eine Funktion kann keine struct, union, Felder oder Funktionen i zurückliefern, nur Pointer auf solche. X und Y sind Parameter, iong X, Y; ist die Parameterdeklaration. Uichtig! In der Parameterüste dürfen keine struct, union, Funktionen oder Felder stehen, nur Poir.'er auf solche sind erlaubt. Z ist eine lokale Variable vom Typ long. Der Funktionskbrper muß in { } eingeschlossen sein. Beim Aufruf einer Funktion werden Parameter vom Typ char nach int gewan delt und solche vom Typ float nach double. VI DIE FUNKTION HAIN Das von anderen Programmiersprachen her bekannte .Kauptprograram ist eine Funktion mit dem Namen MAIN. Sie wird automatisch beim Start des Programms aufgerufen. MAIN kann ohne Parameter oder mit 2 Parametern definiert werden. Mit Hilfe der Parameter kann auf den Text hinter den Programmnamen in der Aufrufzsile zugegriffen werden. Definiert wird folgendermaßen: MAIN (arge,argv) int arge; char »argvCD; arge gibt die Anzahl der Argumente +1 an. argfist ein Pointer auf ein Feld vor. Strings. Jedes Element von argv ist ein Pointer auf die zugehörige Zeichenfolge aus der Aufrufzeile. Der ersie Pointer zeigt aus Kompatibilitätsgründen immer auf einen leeren String. z.B.: Die Aufr^fzeile ist "A>cc /c beispiel'c:'" arge ist gleich 3. argv C13 zeigt auf "/c" und argv [2J zeigt auf "beispiel". VII ANWEISUNGEN AN DEN PREPROCESSOR Der C Compiler enthält einen Preprocessor, der in der Lage ist, Makros zu ersetzen, bedingte Compilation zu veranlassen und Dateien und Assemblertexte einzufügen. Wichtig! Jede Zeile, die den Preprocessor ansprechen soll muß als erstes Zeichen ein # enthalten. Außer der Mitteilung an den Preprocessor darf die Zeile keine weiteren Zeichen enthalten (werden überlesen!) V I I I ERSETZUNGEN Eine Anweisung der rorm iWefine NAME Erseizungszeichen bewirkt, daß überall im nachfolgenden Programm, der Name NAME durch die Zeichenfolae Ersetzunaszeichen ersetzt wird v Beispiel FLAENGE 80 char FELD CFLAENGE3; FELD ist ein Feld der Länge 80 vom Typ Es gibt ebenfalls die Möglichkeit Makros mit Parametern zu erklären. #deflne Name(Name,Name / , Name) Erse'izungszeichen Wichtig! Name und ( müssen unmittelbar aufeinander folgen. Falls zwischen Name und ( z.B. ein Leerzeichen steht, wird Name durch (Name, Name, ..., Nase) Ersetzungszeichsn ersetzt! Beispiel #ceflne ... aus: wird: j SUMME(L, M, K) L + M- ( K ) !i '• UERT = 3 «* SUMME(3 - F, 75, 100 - D); UERT = 3 « 3 - F + 75 - ( 100 - D ); i j i Durch #ur.de£ NAME gilt der Makroeintrag NA?: E als nicht mehr vorhanden. Beispiel Runder SUMME . " falls anschließend UERT = SUMME (l, 2, 3) auftritt, wird angenommen, SUMME sei eine externe Funktion. V I I ? EINFUGEN VON DATEIEN ffinclude Dateiname bewirkt eine Ersetzung dieser Zeile durch de a Inhalt der Datei Dateiname. *include kann nicht geschachtelt werden. Statt Dateiname kann auch "Dateir.änje" oder (Dateiname) stehen. Der Dateiname darf die Zeichen " < > nicht enthalten. j . ; j ',- C-43 5 r a c i i c e = CMre i.;."- V I I 3 BEDINGTE COHPILATION Es gibt drei Formen der bedingten Obersetzing: 1. #if 2. rfifdef konstanter Ausdruck NAHE 3. »•• #ifndef • • • /reise NAME * #else • *t ••• £~ndif «endif \ £else kann auch entfallen. Jedesmal wird überprüft, ob die angegebene Bedingung erfüllt ist. Bei #if gilt die Bedingung als erfüllt, falls der konstante Ausdruck ungleich 0 ist. Bei #ifcsf ist sie erfüllt, wenn der Name NAJ1E durch ^define bekannt gemacht wurde und bei £ifndef, falls NAHE nicht mittels #define erklärt wurde. Ist die 3e-dingung erfüllt, so werden die Zeiten bis zum, #else (falls vorhanden, sonst bis #endif) compiliert. ajiderenfc.ils werden sie ignoriert und die Zeilen zwischen *eise und ?*endif compiliert. Es ist zulassig #if... zuschachteln. Beispiel £cefine H 6 #ifief H Zeile 50 Zeile 100 Zeile 102 * Zeile 110 #i£def HAX Zeile 112 Zeile 130 #endif Zeile 132 ' Zeile 160 Die Zeilen 50 bis 100 werden compiliert, die Zeilen 102 bis 160 ignoriert, VI14 ÄNDERN DER ZEILENNUnnER #line konstanter Ausdruck bewirkt, daß für Fehlerverfolgungszwecke der ermittelte Wert als neue Zeilenaummer aenomaien wird. VII5 EINFÜGEN VON ASS D* 3LERTEXTEN Assemblertext Der zwischen #asa und ±~ndasE eingeschlossene Assemblertext wird unverändert in die Ausgabedatei übernommen. Vor #ASH sollte möglichst eine Leeranweisuiig ( ; ) stehen. Andernfalls kann der Text z.B. nach if an einer unerwünschte.} Stelle eingefügt werden. Beispiel Funktion, die das Byte, das an einein Inputpcrt anliegt, als Funktion swert zurückliefert. INPUT (PORT) i int ?OHT; POP DE PO? BC IN L , ( C ) LD H , 0 PUSH BC PUSH DE #endasm Ein weiteres Beispiel: while ( 1+5 < K f #endasm FUNK (I++); Der eingefügte Assemblertext und der Funktionsaufruf von FUNK liegen beide innerhalb d^r while Schleife, weil #asm nic.v>t als Anweisung angesehen werden kann, sondern der nachfolgende Assembler text unabhängig von der übrigen Codegenenerung unmittelbar in die Ausgabedatei eingefügt wird. C-45 ril - C Ohne genaue Kenntnis des Compilers ist das; Ergebnis des nächsten Beispiels nicht absehbar: hile ( (I -H 5) < K ) FüNK (I-H-); MI - C V I I I . REGELN FÜR DEN GELTUNGSBEREICH VON OBJEKTEN In C hat man die Möglichkeit, den Quellt e::t eines Programmes in mehreren Dateien zu halten und diese getrennt zu conpilieren. Man muß Variablen, die in mehreren Dateien gebraucht werden, in einer Datei so deklarieren, daß ein Zugriff von anderen Dateien aus möglich ist. Mau muß sie also außerhalb von Funktionen deklarieren, (externe Variablen) • . Interne Variaben haben ihre Gültigkeit soLinge, wie der Block existiert in dem sie deklariert wurden. Gleichnamige Objekte aus äußeren Blöcken oder gleichnamige externe Objekte werden für die; Dauer dieses Blockes überdeckt und sind danach unverändert. Externe ObjeKe gelten vom Ort ihrer Definition bis zum Dateiende. Sterne static deklarierte Objekte sind nur in dem Procrammteil bekannt, in dem sie erklärt wirden. Alle anderen externen Obie)cte sind im ganzen Programm mit Namen Dekanat. Es dürfen daher keine zwei unterschiedlichen, globalen Objekte mit gleichem Namen erklärt werden, (auch nicht in verschiedenen Programmteilen) Zu einem Programmteil gehören alle externen Definitionen, die gemeinsam :ji einem Compüerlauf übersetzt werden. Beispiel In den Dateien, in denen die Variable gebraucht aber nicht deklariert wird, muß eine Definition: extern Typ Name; erfolgen. Programmteil l : int PARACJMAXD; char »PTRP2; • • •• Programmteil 2 : extern int P ÄRA C13: extern char »PTHP2; D. BESCHREIBUNG DER BIBLIOTHEKSFUNKTIONEN Für die Benutzung der folgenden Ein- Ausgebe Funktionen sind die Definitionen aus der Datei STDIO.H erforderlich. (u.a. EOF, NULL, FILE). Sie können durch #include STDIO.H ins Programm eingefügt werden. Die Terminalfunktionen sind durch zwei Ma)xodefinitionen auf 4 verschieden Arten einstellbar. Dazu muß die Datei CONIO.H vor der Datei STDIO.H ins Programm eingeschlossen werden. Es bestellt die Möglichkeit ein Echo einbzw. auszuschalten oder Übersetzungen für die Zeichen \n (\r \n) und OX1A (ECF). vorzunehmen. Die Beschreibung dazu befindet sich in der CONIO.H. Ohne die Datei CONIO.H wird mit Echo im ;iSCII-nodus gearbeitet. Wenn die STDIO.H nicht mitüber setzt wird, wird im direkten Modus mit Echo gearbeitet. Für die dateiverarbeitenden FunJctionen stehen für die Umleitung zum Tericinal die Standarddäteizeiger STDIN, STDOUT und STDERH zur Verfügung. Mitteis STDLST und STDAUX kann zum Drucker oder zur Hilfseinheit umgeleitet werden. I. UNFORMATIERTE EIN- AUSGABE Folgende Funktionen stehen für die unformatierte Ein- Ausgabe zur Verfügung: I! EIN- AUSGABE FÜR DAS TERMINAL GETCHAHO f Das nächste Zeichen vom Terminal wird als FunJctionswert zurückgegeben. , UNGETCHAR(c) char c; Das Zeichen c wird der Funktion getchar für den nächsten Aufruf zur Verfügrong gestellt. . f PUTCHAR(c) [ char c; . • Das Zeichen in c wird auf dem Terminal ausgegeben und als Uert zurückgeliefert. CHRRDYO • Der Funktionswert ist l, falls ein Zi?ichen vom Terminal ansteht, 0 sonst. • . PUTS(ptr) char »ptr; Gibt den String ab ptr auf dem Ternunal aus (d.h. bis eine binäre 0 gefunden wird) und dann 'cr"^' l • | t | K E •'.•i •"';! >-• »••'i U' L GETS(buff) char »buff; Eine Eingabezeile wird nach buf: gebracht. ('er' wird nicht übernommen.) Das letzte Zeichen in buff ist eine binäre 0. Der Funktionswert ist die Anzahl der eiageg sbenen Zeichen. PUTLST(c) char c; Das Zeichen in c wird auf dein Drucker ausgegeben und als Wert zurückgeliefert. 12 GEPUFFFEETE DATENVERARBEITUNG Bei CP/M Dateien gibt es einige Besonderreiten. Die Länge einer Datei kann nur Vielfache der Recordlänge (128 Byte ) annehmen. Eine Ausnahme bilden ASCII-Dateien bei denen ein vorzeitiges Ende durch ein Byte OX1A angezeigt werden kann. Außerdem wird das Zeichen '\n' durch die .Folge '\r"\n' repräsentiert. Solche ASCII-Dateien können unabhängig von dieser spezielien Dar Stellung sw eise bearbeitet werden, wenn beim Eröffnen mit FOPEN angegeben wird, daß es sich um eine ASCI."!-Datei handelt. Die Zeichen verarbeitenden Funktionen ermitteln dann das tatsächliche Dateiende und '\n' wird in '\r"\n' gewandelt und umgekehrt. FILE » FOPEN(dateiname, typ) char »dctsiname, *typ; typ kann sein: "R" zum Lesen "U" zum Schreiben "A" zum Anfügen - . i j ] i j ! j ; i l | Zusätzlich zu diesen Grundtypen gibt es bei MI - C folgende zusätzliche Typen: "HA" zum Lesen im ASCII-Modus "UA" zum Schreiben in ASCII-Modus "AA" zum Anfügen an <?ine ASCII-Datei "AR" zum Anfügen eui eine Datei mit zusätzlicher Leseerlaubnis "AAR" zum Anfügen ar eine ASCII-Datei mit zusätzlicher LeseerlauDnis. Die Datei dateiname wird eröffnet. Soli die Datei zum Schreiben eröffnet werden, wird, falls die Datei bereits existiert, die alte Information überschrieben. Existiert noch keine Datei mit dem Namen dateiname, so wird eine neue angelegt. Soll die Datei zum Lesen eröffnet werden, isu3 die Datei dateiname bereits existieren. Anders als beim lyp "U" oder "A" liefert das Eröffnen einer noch nicht existierenden Datei einen Fehler. Im Fehlerfali wird NULL (Null-Pointer) zurückgegeben. Falls kein Fehler aufgetreten ist, wird ein Pcinter auf die Dateibeschreibung zurückgegeben, der bei getc, putc, fread, fwiite, ungetc, fcicse benutzt werden kann. i Besonders behandelt werden die Dateinamen con:, aux: und Ist: , die den Zeichenstrora auf das Terminal, zur Hilf seinheit bzw. ' zum Drucker lenken. Bei con: kann der in der CONIO.H eingestellte Modus des Terminal"anschlußes übernommen werden, wen:i vor dem FOPEN der globalen Variablen CHIOMOD der wert STDINx zugewiesen wird. Beim reservierten Namen Ist: wird ctor Ducker im direkten Modus angesprochen, außer wenn der Typ bei FOPEN start "W "wa!I ist. Dann wird \n in \r\n gewandelt. Die Anzahl der gleichzeitig eröffneten Dateien ist nur durch den Speicherplatz begrenzt. Die Typen "AP?" und "AAR" können nic:ht bei einer CP/M Version kleiner als 2.0 benutzt werden. • Beispiel: FILE »fp; fp = fopen("B:ZZLC", "I?1); FCLOSI(fp) FILE »fp; Die zu fp gehörige Datei wird geschlossen und der Puffer freigegeben. Im Fehlerfall wird EOF zurückgegeben, sonst 0. F?UTS(ptr,fp) FILE »fp; Wie PUTS(ptr) nur wird in die zu fp gehörige Datei geschrieben. Bei Fehler oder Dateiende wird EOF als Wert zurückgegeben. FGETS(buff,max,fp) eher »buff; int max; FILE »fp; Die nächste Zeile aus der zu fp gehörigen Datei wird nach buff gebracht. Das Zeichen '\n' wird mi': übernommen. Eine binäre Null wird ans Ende angefügt. Es werden höchstens max- 1 Zeichen gelesen. Im Fehlerfall oder bei Dateiende uird NULL zurückgegeben, sonst buff. GETC(fp) FILE »fp; GETC(fp) gibt das nächste Zeichen eus der zu fp gehörigen Datei zuräck oder, falls das Dateiende erreicht ist oder ein Fehler aufgetreten ist, EOF. Falls zu fp eine iia ASCII-Modus eröffnete Datei gehört, wird auch beim' Auftreten von OX1A EOF zuruckgeliefert. int c; FILE »fp; Mit UNGETC(c,fp) wird das Zeichen c: in die zu fp gehörige Datei zurückgegeben. Beim nächsten Aufruf von GETC etc. wird dieses Zeichen c verarbeitst. Falls es nicht möglich ist, das Zeichen c in die Datei zurückzuschreiben (z. 'B. c gleici EOF ist oder im Fehlerfall) wird EOF zurückgegeben, sonst wird das Zeichen c zurückgegeben. Wenn die Datei eine zusätzliche Schr=iberlaubnis hat, kann mittels UNGETC die Datei verändert werden. jj ;j jj ?UTCic,fp> int c; FILE »fp; Mit PUTC(c.fp) wird das Zeichen c in die zu fp gehörige Datei geschrieben und der Wert c zurückgegeben. Falls das Zeichen nicht* in die Datei geschrieben werden Jconme (z.B. Platzmangel oder Fehler), wird EOF zurückgegeben. FURITE(bu£,laenge,zahl,fp) char «buf; unsignsd laenge, zahl; FILZ "fp; zahl oft werden laenge viele Zeichen aus dem Puffer buf in die durch fp gekennzeichnete Datei geschrieben. Falls die gewünschte Zeichenzahl in die Datei geschrieben wurde, wird zahl zurückgegeben. Falls (z.H. durch Platzmangel verursacht) nicht die gewünschte Zeichanzahi in die Datei geschrieben u erden konnte, wird die Anzahl der tatsächlich geschriebenen Zeichen in Vielfachen von iaer.ge zurückgegeben, d.h. Ein Fehler ist aufgetrsien, falls die Zahl dsr zu schreibenden Zeichen nicht mit der zurück gegebenen Anzahl übereinstimmt. FREAD(buf,laenge, zahl, f p) char »buf; unsigned laenge, zahl; FILE «fp; zahl oft werden laenge viele Zeichen aus der durch fp gekennzeichneten Datei in den Puffer buf gelesen. Zurückgegeben wird wie oft laenge viele Zeichen aus der Datei gelesen wurden. Is Fehlerfall (z.B. Datei nicht zum Lesen eröffne':) wird 0 zurückgegeben. FSEEKIf p, offset, origin) FILE "fp; long offset; int origin; Durch FSEEK(fD,o£fset,criain) wird die aktuelle Position in der zu A ' ' ^ fp gehörigen Datei verändert. origin kann sein: 0 für Position /om Dateianfang aus um offset verändern 1 für Position von aktueller Position aus um offset verändern 2 für Position \om Dateiende aus um offset verändern Sollte die ermittelte Position "vor der Datei liegen, so wird auf Dateianfang positioniert. Beim nächsten Zugriff auf die Datei wird ab der neu ermittelten Position gearbeitet. la Fehlerfall (z.B. ermittelte Position zu hoch, origin unzulässig) wird EOF zurückgegeben. FSEEX kann nicht bei einer CP/M Version kleiner als 2.0 benutzt werden. Beispiel: Das folgende Programm kopiert eine Datei v.m, wobei der Quelldateinaiue und der Zieldatsiname am Terminal angefragt werden. #include 5TDIO.K mainO FILE «eunit, «aunit; char lineCSO], c; s ID i 10 ine PUTS ("\r\neingabedatei :"); GET5( Line); if((eunit=FOPEN(line,"R"))==NULL) return errorO; FUTS ("\r\nausgabedatei :"); GETS (line); if((aunit=FOPEN(line, M w"»==NULL) return errorO; while ((c= GETC(eunit)) != EOF) if (PUTC (c,aunit) == EOF) re'iurn errorO; if (FCL05E (aunit) == EOF) errorO: } error() ( PUTSr\r\nFEHLEE BEIM KOPIEHEN") 13 UNGEPUFFEE7E DATEIVERARBEITUNG Da das CP/tf Betriebssystem nur Vielfache von Records ( 1 2 8 Byte) aus Dateien liest oder hinein schreibt, muß bei der ungepufferten Ein- Ausgabe, wenn die Recordgrenzen nicht eingehalten werden, trotzdem zwischengepuffert werden. (z.B. wenn bei READ oder UHITE die Länge einmal kein Vielfaches von 128 ist oder mit LSEEK nicht auf Recordgrenze positioniert wird.) Dadurch wird dann der Zugriff langsamer. Usnn mit READ oder URITE jedesmal nur wenige Zeichen bei einem Aufruf verarbeitet werden sollen, bietet i. a. die gepufferte Ein- Ausgabe wesentlich kürzere Verarbeitungszeiten. Die ungepufferte Ein- Ausgabe kann bei einer CP/n Version kleiner als 2.0 nicht benutzt werden. OPEN(dateinarae,typ) char »dateiname; int typ; typ kann sein: 0 zum Lesen 1 zum Schreiben 2 zun Lesen und Aniugen Mit OPEN(dateiname,typ) wird die Dctei dateiname, die bereits existieren muß, eröffnet. Im Fehlerfa.l (z.B. typ unzulässig, Datei existiert noch nicht) wird -l zurückgegeben. Sonst wird die DateibeSchreibung, die eine int ist, zurückgegeben. z.B. int fd; fd = OPEN rSSP',2) Im Fall typ = l (schreiben) wird der alte Dateiinhait überschrieben, falls nicht mittels Iseek ans Dateiends positioniert wird. Die Anzahl der gleichzeitig eröffneten Dateien ist nur durch den Speicherplatz begrenzt. CREAT(dateiname.typ) char *dateiname; int typ; Mit CREAT(dateiname,typ) wird die Datei Dateiname neu angelegt, falls sie noch nicht existiert. Falls die Datei bereits existiert, wird '- ' • • • . . • " - U -ö die alte Information gelöscht. In beiden Fällen ist die Datei zum Lesen und Schreiben eröffnet. Übe: Typ kann die Datei mit einem Attribut versehen werden. Möglich sind (auch gemischt): Bit 0 gleich l: Schreibschutz, Bit l gleich i: Systeindatei Bit 2 gleich 1: Archivbit (von CP/K 2.2 nicht benutzt). Im Fehlerfall (kein Platz mehr etc:.) wird -l zurückgegeben, sonst die Dateibeschreibung. CLGSE(fd) int fd; Die mittels OPEN oder CREAT eröffnete Datei, die durch fd bestimmt wird, wird geschlossen. Der von der Dateibeschreibung benötigte Platz wird wieder freigegeben. In Fehlerfall wird -l sonst 0 zurückgegeben. BEAD(fd,buff,n) int fd; eher *buff; int n; Mit HEAD(fd,buff,n) werden n Zeichen aus der Datei, die durch fd gekennzeichnet ist, in den Puffer ruff gelesen. Zurückgegeben wird die Anzahl Zeichen, die gelesen wurde. Im Fehlerfall wird -l zurückaeceben. ^ ^ yRITE(fd,buff f n) int fd; char »buff; int n; Mit U T H17i{fd,buf£,n) werden n Zeichen aus dem Puffer buff in die Daiei. die durch fd gekennzeichnet ist, geschrieben. Zurückgegeben, wird die Anzahl der tatsächlich geschrieben Zeichen. Es ist ein Fehler (Datei nicht zum Schreiben ;eöffnet oder Platzmangel etc.) aufgetreten, falls die vorgegebene Zuhl n nicht mit der zurückgegebenen Anzahl übereinstimmt. LSEEK( f d, of f set, origin) int fd; long offset; int origin; Durch LSEEXtfd, off set, origin) wird die aktuelle Position in der zu fd gehörigen Datei verändert. origii. kann sein: 0 für Position vom Dateianfang aus um offset verändern 1 für Position von aktueller Position aus um offset verändern 2 für Position vom Dateiende aus uz offset verändern Sollte die ermittelte Position "vor" der Datei liegen, so wird auf Dateianfsng positioniert. Beim nächsten Zugriff auf die Datei wird ab der neu ermittelten Position gearbeitet. Im Fehlerfall (z.B. ermittelte Position zu hoch, origin unzulässig) wird -l zurückgegeben. ISEEX(fd,off set, origin) int fd, offset, crigin; Beschreibung siehe LSEEK. ; / REUIND(fd) int fd; In der Datei, die durch fd angegeben ist, wird die aktuelle Position auf den Dateianfang gesetzt. II. FORMATIERTE EIN- AUSGABE Die folgenden Funktionen können für die formatierte Ein- Ausgabe verwandt 'werden. Ihnen ist gemeinsam, daß der eiste Parameter ein String ist, aus dein die Anzahl der ein- oder auszugebende: Werte hervorgeht. Außerdem kann die Form der Ein- Ausgabe an diesem Stnng abgelesen werden. SCANF( CONTROL, ARG l, ARG 2, ...) CONTROL ist ein String, und ARG l, .... sind Pointer auf Objekte, die in CONTROL beschrieben sind. SCANF liest Zeichen vom Terminal, interpretiert sie gemäß CONTROL, und speichert das Ergebnis anschließend an die Stelle, auf die der zugehörige Pointer ARGi zeigt. Wichtig!! Die Anzahl und der Typ der Parameter muß den Angaben im Controlstring entsprechen. Anderenfalls kann das Programm ohne Vorwarnung zerstört werden. Die Argumente müssen Pointer sein. !!! SCANF liefert die Anzahl der erfolgreich weggespeicherten Werte zurück. Bei Dateiende wird EOF statt 0 zurückgeliefert. Zum CONTRCL STRING: i 31anks, Tabs, Newlines werden ignoriert. Umwandlungsspezifikationen haben folgende Form: 5 »(optional) Zahl (optional) Umwandlungszeichen Die Eingabe wird übersprungen, d.h. a.cht weggespeichert. Zahl: * ' Maximale Länge des Eingabefeldes, das jemäß dem folgenden Format bearbeitet werden soll. Das Eingabefeld besteht aus Zeichen, die verschieden sind von Tab, Newline, Blank. Das Ende des Eingabefeldes wird bestimmt durch Zahl oder durch Blank, Tab oder Newline. • Folgende Umwandlungszeichen gibt es: D,d,H,h Die Eingabe wird als dezimale Zahl vom Typ int int er pretiert. 0,o Die Eingabe wird als oktale Zahl ohne führende Null interpretiert. Bei Angabe von Zahl wird diese 0 mitgezähl:. Beispiel Durch SCANF("*2o X2o",&OKZAHLl, &OKZJ.HL2); wird bei der Eingabe 34 034 nach OKZAHL1 die Zähl 34 gespeichert und nach OKZAHL2 eine 3. X,x Die Eingabe wird als hexadezimale Zail ohne führendes OX interpretiert. Bei Angabe von Zahl werden OX mitgezählt. Das zugehörige Argument sollte für di<= Fälle: D,d,H,h,0,o,X,x ein int Pointer sein. ii C,c Das nächste Eingabezeichen wird als ASCII - Zeichen interpretiert. Das zugehörige Argument sollte ein char Pointer sein. In diesem Fall werden Blanks, Tabs, Newlines nicht überlesen, sondern an die durch das entsprechende Argument angegebene Adresse gespeichert. S,s Die Eingabe wird als Folge von char (String) aufgefaßt. Das zugehörige Argument sollte auf ein Feld vom Typ char zeigen, das groß genug ist, die char Folge und eine binäre Null (als Endezeichen) aufzunehmen. Beispiel char FELC5]; SCANF("X4S', ScFEL): ist bei jeder Eingabe möglich. Aber bei SCANFC'XS', ScFEL); mit der'Eingabe COMPUTER passiert folgen• des: COMPUTERN wird ab FEL weggespeiciert. COKPU wird innerhalb der Feldgrenzen abgelegt, aber TERD wird übe: die Feldgrenze hinweg gespeichert und zerstört der: den SDeicherinhal:. Die Eingabe wird als Gleitkommazahl aufgefaßt. Die Eingabe kann so aus sehen: [-]nnnnn.nnnEC-Dnnn Beispiel float RA; speichert die folgenden Zahlen nach RA: 100 oder 1.E2 oder 100. OEO oder O.OOD1E6 ... Folgende Eingabewerte sind unzulässig: .E oder 3 5. E oder 0.3.4 oder E usw. Zulässig sind Eingabewerte, die höchstens einen Punkt (ein E (e)) enthalten, und falls E (e) vorkommt, danach auch eine Zahl. Bei 5CANF("*5F', ScRA ); würde die folgende Eingabe eine Fehlermeldung verursachen: 234. E4 (die Zahl nach E wird nicht verarbeitet!) Falls in den Fällen D,d,H,h,C,o,X,x, den Jm Wandlungszeichen ein L oder l vorausgeht, wird angenommen, daß das zugehörige Argument ein Pointer auf Icng ist. Entsprechend gibt ein L oder l vor F,f,Z,e an, laß das Argument ein Pointer auf double statt float ist. Beispiel double DOU; bei SCANFC'JE", &DOU); werden nach DOJ nur 4 Byte gebracht, die anderen 4 enthalten noch ihren alten Wert, so daß der in DOU enthaltene Uert verschieden ist vom eingegebenen Uert. Es süß hier also SCANF'rSLE", iDOÜ) m heißen. Falls im CONTROL STHING ein Zeichen auftritt, das mit keinem zulässigen Um Wandlungszeichen übereinstimmt, wird der Inhalt des Eingabestroms solange ignoriert, bis er Bit diesem Zeichen übereinstimmt. Hinter dem Zeichen wird die Bearbeitung fortgesetzt. Beispiel long k; int ij; float m; ' char feld C103; SCANF ("2d :2d :»3d tld Y *4f 2s", &i, &], &Jc, &m, feld) £iiigai>esrroin: 10231 1289834567 8910Y8125ttI-C liefert: 10231 -> i, 12 -> 3, 898 wird Übergängen, 34567 -> Je/ 8910 wird ignoriert, Y stinjnt mit dem Zeichen im COKTHCL STHING überein, 3125 -> m, -) feld. - C " •' ' PRINTF(CONTRCL, ARG1, ARG2, D-'IO ...) CONTROL ist ein String, und ARG l, .... sind die Werte, die auf dem Terminal ausgegeben werden sollen. PRINTF formatiert die Arguments ARG l, ARG2, ... entsprechend den Angaben im CüNTHOL STRING, bevor sie ausgegeben werden. Alle Zeichen aus CONTROL, iiie keine gültigen Formatsteuerungen mit vorausgegangenem * sind, werden unverändert mit ausgegeben. Beispiel: Lit h; h=60; PRINTF (" Auf der Uiese sitzen .so Hasen." ,h) liefert die Ausgabe: Auf der Uiese sitzen 74 Hasen. Nichtig!! FRINTF erwartet sovlele Argumente, wie aus den Angaben im Controlstring ermittelt werden. Wenn zu wenige Argumente vorkommen, oder wenn der Typ der Argumente mit dem jeweiligen Uinwancüungsz eichen nicht vereinbar ist, gibt es unsinnige Ergebnisse. Beispiel ) long Ll; int II, 12, 13, 14: PRINTF ("Je Sd Sd Sd *d", II, 12, 13, 14, Mit *e werden die acht Byte von II, 12, 13 und 14 als "double" ausgegeben. Mit Xd werden die zwei höherwertigen Byte von L l als "int" ausgegeben. Mit dem nächsten *d werden die niederwertigen Byte von L! als "int" ausgegeben. Die nächsten zwei Xd holen die nächsten vier Byte aus dem Stack und sie werden als zwei "int" ausgegeben. (Unsinnige Ausgabe., Stack nicht mehr richtia) Zeichen, die Umwandlung und Ausgabeforaat beeinflussen: v 4» Jede Umwandlungsbeschreibung beginnt mit S. Falls man ias Zeichen l ausgeben möchte, muß man r* schreiben! " Das umgewandelte Argument wird linksbündig im Ausgabefeld abgelegt, sonst rechtsbündig. - hat nur Auswirkungen, wem das Ausgabefeld größer ist als die Ausgabe. 1.Ziffernfolge Die Zahl gibt die minimale Ausgabefeldlänge an. Ist cüe Ausgabe länger, wird auch das Ausgabefeld verlängert. Is": die minimale Ausgabefeldlänge größer als die Ausgabe, so wird das Auscabefeld, je nachdem ob '-' gesetzt ist oder nicht, rechts oder links mr: ' ' aufgefüllt. Falls die Ziffernfolge mit 0 beginnt, wird das Auffüllzeichen ' ' durch '0' ersetzt. . Trennungszeichen zwischen 1. und 2.Ziffernfolge (Die Angabe t 1. Ziffernfolge .'0 und X l. Ziffernfcige . ohne zweite Ziffernfolge liefern das gleiche Ergebnis) " 2.Ziffernfolge Die Zahl gibt die maximale Anzahl der Zeichen an, die von einer char Folge gedruckt werden sollen, bzw. bei douole und float Zahlen die Stellenzahl nach dem DezimalounJct. l | r ' L, l L oder l gibt an. daß das zugehörige Arguuent vom Typ long ist. Umwandlungszeichen: D,d Das Argument wird als Dezimalzahi ausgegeben. 0,o Das Argument wird als Oktalzahl ohne Vorzeichen und ohne führende 0 ausgegeben. X,x Das Argument wird als Hexadezimalzahl ohne Vorzeichen und ohne führendes OX ausgegeben. U,u Das Argument wird als Dezisalzahi ohne Vorzeichen ausgegeben. C,c Das Argument wird als Zeichen vom Typ char aufgefaßt. S,s Das Argument ist ein String. Es werden solange Zeichen ausgegeben, bis der String zu Ende ist (binare 0) odur die Anzahl der Zeichen, die durch die 2.Ziffernfolge angegeben wirci, erreicht ist. In den beiden folgenden Fällen ist dss Argument eine Zahl vom Typ float oder double: E,e liefert: C-]m.ddd...d£[+-]nnn Die Anzahl der d ist gleich 6, falls keine 2.Ziffernfolge angegeben ist, s^nst gleich der dort angegeben Zahl (maximal 13). F,f Liefert: [-]mramra.däd...d Anzahl d wie bei E,e. G, g je nachdem ob E,e oder F,f die kürzere Ausgabe darstellt, wird nach E,e oder F,f umgewandelt. , ' Jedes Zeichen nach X, das mit keinen Umwanclungzeichen übereinstimmt, wird nach der Angabe 1. Ziffernfolge . 2. Ziffern folge genauso wie die umgewandelten Argumente ausgegeben. Falls die Angcibe 1. Ziffernfolge . 2. Ziffernfolge fehlt, werden diese Zeichen genauso ausgegeben, wie sie nach X stehen, also genauso wie Zeichen, denen kein X vorausgeht. j ' r Beispiel FRINTF r :ni-C-COMPILER"); liefert die gleiche Ausgabe wie PRINTF ("MIC-COMPILER"); nämlich: MI-C-COMPILER aber PRINTF ("SO 10.7MI-C-COMPILER"); lisfE-rt die Ausgabe B H oocni-c-co und PRINTF ("010. TMI-C-COHPILER"); liefert 010.7MI-C-COMPILER . jj . double z; z enthält 432.56733345 ?HINTF(":-015.3E",z) liefert- +4.32GE-r-OOi 0000 PRINTF ( " X O l S . S P ^ z ) liefert 00000000432.568 ' s | I ! | l i i p SSCANFfSTRING, CONTROL, ARG1, ARG2....J char *STRING; Beschreibung siehe SCANF. Statt von der Star, dar t eingäbe werden Zeichen aus STRING nach den Angaben in CONTROL an die Stellen gespeichert, auf die das jeweilige Argument zeigt. SFRINTF(STRING, CONTROL, ARG1, ARG2,..,) char »STRING; Beschreibung siehe PRINTF. Wie bei PRINTF werden auch hier ARG l, ARG2, ... so umgewandelt, wie es CONTROL angibt. Die Ergebnisse der Umwandlungen werden in STRING abgelegt. FSCÄNFIF, CONTROL, ARG l, ARG2, ...) FILZ *F; . . . Beschreibung siehe SCANF. • Die Zeichen werden aus der zu F gehörigen Datei (mit FOPEN eröffnet) nach den .Angaben in CONTROL an die Stelle gespeichert, auf die das leweilige ARG! zeigt. F?RINTF(F, CONTROL, ARG l, ARG2, ...) FILE *F; f Beschreibung siehe PRINTF. Die umgewandelten Argumente ARG l, ARG 2, ... werden in die zu F gehörige Datei geschrieben. ! j III. ALLGEMEINE SYSTEMFUNKTIONEN BDCS(DE.C) ' char «DE; int C; Eine Eetriebssystemleistung wird angefordert. Die BDOS Funktion, deren Nummer im Parameter C steht, wird mit dem Eingabeparameter aus Parameter DE ausgeführt. Das Resultat wird als Funktioswert zurückgeliefert. z.B. BDOSrA',2); gibt ein A auf dem Terminal aus. C"Y _"""TV _ *_y\ i. v\/ _EXIT bewirkt sofortigen Programmabbruch. int n; EXIT bewirkt einen Programmabbnich durch Aufruf von _EXIT, nachdem vorher alle offenen Dateien geschlossen wurden. Der Parameter n hat keine Bedeutung. CHA IN (name, parameter) char *narae. «parameter; CHAIN schließt alle Dateien, beeniet das laufende Programm und startet das Programm aus der Datei aame, wobei im String parameter Information weitergegeben werden kaiin. Der String muß genauso aufgebaut sein wie die Kommandozeile für den CCP. Z.B. cHAiNC'cc.coirv/T BEISPIEL"); CLOSALO Hit CLOSALO werden alle offenen Dateien geschlossen. Hierbei ist es Gleichgültig ob sie mit fopen, open oder creat eröffnet wurden. UNLINK(name) char«name; Hit UNLINK(name) wird die Datei na'ae aus dem "Deteienverzeichnis" gelöscht. Hierbei ist es egal ob die E-atei eröffnet ist oder nicht. I | j i . j , ; j IV. 57RINGFUNKTIONEN S7HC?Y(strz,stra) char «strz, »stra; Der Ausgangsstring stra wird in den Zieistring SITZ kopiert. S7H.\'CFY(strz,stra,max) char *strz, »stra; int sax; Vom Ausgangsstring stra werden maximal raax viele Zeichen in den Zieistring strz kopiert. Eventuell sieht dann in strz ein String, der nicht durch \0 beendet wird!! '(strl,str2) char »strl, »str 2; strl und str2 werden miteinander verglichen. Falls alle Zeichen aus strl mit denen aus str2 übereinstimmen, wird 0 zurückgegeben. Falls in String strl ein Zeichen gefunden wird, das nicht mit dein entsprechenden Zeichen aus str2 übereinstimmt, wird die Differenz dieser beiden Zeichen zurückgegeben. Talls das Zeichen in strl einen kleineren Uert hat als das in str 2. eine negative Zahl sonst eine positive. S7RNC?!?(strl,str2,max} char «strl, »str2; * •-. J- O.:IL T" — 1^ * IDcJC, Uie S7RCHP, aber nur maximal max vi{?le Zeichen werden verglichen. S7RLZN{str) char *str; S7RLEN(str) gibt die Länge des Striiigs str zurück. Die binäre Null am Ende des Strings wird nicht mitgezählt. S7RCA7(strl,str2) char »strl, »str2; Der String str2 wird an das Ende d=s Strings strl angefügt, strl zmß groß genug gewählt werden! STHNCATt str l, str 2 ; max) char »strl. «str2; int max; Vora String str 2 werden höchstens max viele Zeichen an das Ende des Strings strl angefügt. Eine binäre Nul. wird ans Ende gesetzt. char -STHSAVE(str) char »str; S7HSAVE sichert den String str in ein=n mit CALLOC bereitgestellten Platz und gibt einen Pointer darauf :~urück. Falls mit CALLCC kein Platz mehr zur Verfügung gestellt werben konnte, wird NULL zurückgegeben. t IA T char »strl, »str2; Es wird überprüft, ob str2 in strl enthalten ist. Falls nein, wird eine -l zurückgegeben. Falls ]a, ward die Position zurückgegeben, an der str2 in strl anfängt. --------char *RINDEX(strl,str2) char »strl, *str2; RIfJDEX arbeitet wie INDEX. Aller iings wird, falls str2 mehr als einmal im String strl enthalten ist ein Pointer auf das letzte Auftreten zurückgegeben. V. TI57- UND UHUANDL'JNGSFUNKTIONEN In der Bibliothek stehen Doch folgende Test und Umwandlungsfunktionen zur Verfügung: ISALPHA(C) int C; liefert ein Zeichen ungleich 0 zurück, falls das Zeichen aus C ein (klein oder groß geschriebener) Buchstabe ist, sonst 0. ISUPPEHfC) int C; liefert ein Zeichen ungleich 0 zurJck, falls das Zeichen aus C ein groß geschriebener Buchstabe ist, sonst 0. ISLOUER(C) int C; liefert ein Zeichen ungleich 0 zurück, falls das Zeichen aus C ein klein geschriebener Buchstabe ist, sonst 0. t ISDIGIT(C) int C; liefert ein Zeichen ungleich 0 zurück, falls das Zeichen aus C eine Ziffer ist, sonst 0. ISALNUK(C) int C; \ liefert sin Zeichen ungleich 0 zurück, falls das Zeichen aus C ein Buchstabe oder eine Ziffer ist, sonsr 0 ISASCIKC) int C; liefert ein Zeichen ungleich 0 zurück, falls das Zeichen aus C ein ASCII-Zeichen ist, 0 sonst. ISSPACE(C) int C; liefert ein Zeichen ungleich 0 zurücc, falls das Zeichen aus C = ' ' oder '\7' oder 'W oder '\H' ist, sor.st 0. TOLOUER(C) int G: TOüPPEH(C) int C; liefert den klein geschriebenen Buov Stäben aus C zurück, falls das Zeichen in C ein Großbuchstabe ist, sonst das Zeichen selbst. liefert den groß, geschriebenen 3uch5;taben aus C zurück, falls das Zeichen m C ein klein geschriebener Buchstabe ist, sonst das Zeichen selbst. • • ATOI(strl) char «strl; Der String strl wird in eine' Zahl vom Typ int umgewandelt. j S double ATOF(strl) ! ' char »strl; Der String strl wird in eine Zahl vom Typ double gewandelt. • ] j iong ATOL(strl) char »stri; Der String strl wird in eine Iong Zahl umgewandelt. ITOA(zahl,str) int zahl; char *str; Die Zahl zahl wird in eine Folge von ASCII - Zeichen gewandelt AES(n) int n; A3S(n) liefert den Absolutbetrag der :'jit n zurücJc. Iong AHSL(n) Iong n; liefert den Absolutbetrag der Iong Zald n zurück. double ABSD(n) double n; liefert den Absolutbetrag der double Zahl n zurück. \l T r 1 r~~^ *~ •*• f~~ T T— »^n r •, T"~T 7 ~ " ~ > f * n ' TTXTi' " VI . S r niCrünrLnT^ /r.r.wAL.1 JNG char «MALLOC(laenge) unsigned laenge; Mit M^.LLOCdasnge) wird freier Speicherplatz für laenge viele Zeichen angefordert. Es wird NULL zurückgegeben, falls nicht genügend freier Platz mehr vorhanden ist. juidersnfaüs wird ein Pointer auf einen freien Speicherbereich, der mindestens laenge viele Zeichen aufnehmen kann, zurückgegeben. char «CALLOCfn, laenge) UTiSigned n, laenge; CALLOC(!i,iaengr) arbeitet wie MALJ.OC. Es wird Platz für n*laenge viele Zeichen angefordert, wobei der Speicherplatz mit 0 vorbesetzt wird. t CFHEE(ptr) char *ptr; Mit CFHEE(ptr) wird der mit CALLOC angeforderte Speicherplatz wieder in die Liste des von CALLOC verwalteten freien Speicherplatzes zurückgegeben, ptr muß ein von CALLOC gelieferter Pointer sein! char *S5HK(n) unsigned n; Mit SSHKin) wird weiterer Speicher von n Byte Lange angefordert. SBRK liefert einen Pcmter auf d=n freien Speicherplatz zurück oder, falls kein Platz mehr zur Verfügung gestellt werden NULL. Man beachte, dai? bei gleichzeitiger Benutzung von 5BRK und CALLOC der Speicher von CALLOC möglicherweise nicht mehr effektiv verwaltet werden kann. j j j i l V I I . MATHEMATISCHE FUNKTIONEN Die mathematischen Funktionen sind vor dem Aufruf als 'extern double...()' zu definieren. Die Argusente müssen den Typ float oder double haben. Uenn ein Argument erkennbar außerhalb des Definitionsbereichs der betreffenden Funktion liegt, wird die Funktion int CFFEER (i) aufgerufen. CFODIV aufgerufen wenn i gleich 0 ist, sor:st CFOVERFLOU. Dort wird Die trigonometrischen Funktionen erwarten Argumente im Bogenmaß und keiae Pinkel. double SIN(x) double x; liefert den Sinus von x zurück. double COS(x) double x; liefert den Cosinus von x zurück. double TAN(x) double x; liefert den Tangens von x zurück. double ARCTAN(x) double x; liefert den Arcustang-ns von x zurück. i i j double LN(x) double x; . j liefert den Logarithmus von x zur Basis e zurück. 3 ui j l« double LOG(x) double x; liefert den Looarithmus von x zur Basis 10 zurück, ii ilr double EXP(x) double x;* liefert den Usrt vcn e hoch x zurück. n11 ij double EX?lö(x) jj double x; liefert den Wert von 10 hoch x zurück. ' double ?CT(y,x) double x,y; ' liefert den Wert vcn y hoch x zurück. • . , j double SQRT(x) double x: liefert die Quadratwurzel von x zurück ' 6 (i £. LISTE DES E I N S C H R Ä N K U N G E N , ERWEITERUNGEN , BESONDERHEITEN - #include darf nicht geschachtelt sein (d.h. eine mittels #include eingefügte Datei darf kein weiteres #include enthalten)- Variablen, Felder und Strukturen werden nicht automatisch mit 0 vorbesetzt (aber: Felder und Strukturen, bei denen mindestens ein Element initialisiert ist, werden mit 0 aufgefüllt) Diese Einschränkung gilt nicht bei der Verwendung von M 8 O/ L 80. - Bitfelder (bei Strukturen) gibt es nicht - Variablen vom Typ float oder double kön.ien nur mit Konstanten vom Typ double initialisiert werden. (also: float a = 1.0; aber nicht: float a = l; ) - Namen und Typen von Elementen von Strukturen unterliegen nicht der Beschränkung, daß nur solche Elemente aus; verschieden Strukturen gleichnamig sein dürfen, die gleichen Typ und ileichen Abstand vom Anfang der ]eweilicen Struktur haben. - Bei switch (AUSDRUCK) darf AUSDRUCK euch den Typ long oder double haben. Dann muß hinter case eine Konstant* vom gleichen Typ stehen. - Ein Poinier, auf den andere arithmetisch = Operatoran als Addition oder Subtraktion angewandt werden, wird behanlelt, als wäre er eine Variable vom Typ unsigned. - die Anweisung" .^asm ... £endasm ist hinzugekommen. Alle Zeilen, die dazwischen stehen, werden unverändert in die Ausgabedatei gegeben. So können Assemblerprogramme an geeigneten Stellen des C - Programms eingefügt werden. Z.B. : a) i n p u t O U { . #ASN IN 0 b) o u t p u t O (by te ) int b y t e ; { byte; <:) ou t p u t O (by te ) int b y t e ; ( #asm #ASM MOV L ,A • MOV A ,L POP B POP H HVI H , 0 2ENDASM OUT 0 #ENDASM PUSH H PUSH B } } MOV A , L OUT 0 #eridasm } in put 0 liefert ein B^»te von Port 0 als Funktionswert zurück und Output gibt eines aus. b) funktioniert so nur unter der Option X. c) kann in jedem Fall verwendet werden. . I » ZAHLENDARSTELLUNG Ganzzahlige Typen sind Binärzahlen piement dargestellt werden. Typ: Zahl: HEX: -128 8 OH Typ: Zahl: HEX: 0 0 Tv r-: JL . HEX: Typ: Zahl: •32768 8000K 0 0 Typ: Zahl: 21474S3648 HEX: 80000ÖOOH char -1 FFH wobei negative Zahlen im Zweierkoni- 0 0 1 01H char (Option S ) i 01H int -l FFFFH 0 0 255 FFH l OD01H unsigned l 0001H long -l FFFFFFFFH 127 7FH 32767 7FFFH 65535 FFFFH 0 0 l OCC00001K 2147483647 7FFFFFFFH Gleitkommazahlen haben eine gepackte BCD Zihl als Mantisse und einen l Byte langen binaren Exponenten (zur BASIS 10) mit einem Offset von 128. Der Exponent OK bedeutet, daß die ganze Zahl unabhängig von der Mantisse 0 ist. Zahlen ungleich 0 sind immer normalisiert, d.h. die höchstwertige Ziffer der Mantisse einer positiven Zahl ist ungleich 0 und hat den Wert 'Ziffer » 10 ** -l'. Negative Zahlen werdsr im neuner Komplement dargestellt. Beim Typ float ist die Kantisse 3 Byte lang ( 5 Stellen) und beim Typ double 7 Byte (13 Stellen). Gerechnet wizd lEner mit 13 Stellen, wobei die 14-ts Stelle zum Runden berücksichtigt wird. Extremwerte: (higr ) Hex (low) Zahl Q ^QQQQQQQQQQ^QQ * * 127 10 FF 09 99 99 99 99 99 99 Q CGQQGOQOgOQQQ 10 « * 127 FF 9C CG 00 00 00 00 01 0 00 »10 »«(-127) 01 01 00 00 00 00 00 00 0.1 . 0.1 »10 »*(-127) 01 99 00 00 0000 00 00 G . GESCHlv'INDIGKEITSCPTinilKUNG 'i.A.' bedeutet hier, daß in komplizierteren Ausdrücken durch Optimierung leichte Verschiebungen stattfinden können. - Statische und externe Variable erlauben einen schnelleren Zugriff als temooräre (SDeicherklasse auto). * ^ - Die zuletzt deklarierte, temporäre VariaMe der Lange 2 Byte (keine temporäre Variable im gleichen oder einein innereren Block danach erklärt), erlaubt i.A. einen schnelleren Zugriff a] s andere temporäre Variable. In VA-H- oder. ++VA ist eine wie vor beschriebene Variable i.a. 'schneller' als eine statische oder externe Variable. - Variablen vom TVD float sind 'langsamer* als solche vom TV^ —D double und * * «* diese 'langsamer' als die vom Typ long und diese 'langsamer' als die übrigen. - Variable vom Typ char können mit Option S schneller 'geholt' werden als ohne. Das Abspeichern ist zeitgleich. - der Typ char ist unter der Option S schneller. - Nach float va; ist va = l.i; schneller als va = 1; ca keine Typuswandlung stattfindenmuß. - Ein for hat einen Assesbier JMP in di-3 Schleife hinein mehr als die äquivalente while Anweisung. - Sei definiert static int ch; a) if (ch == 'A') . eise if (ch == 'D') .. ?lse .. b) switch(ch) (case 'A': ... case 'D': > b) ist schneller als a). Ab 3 Alternativen ist b) auch kürzer als a). - *(ptr + x) ist das gleiche wie ptrCx]. n 11. ncrn i H . ANSCHLU55 VON ASSEnSLSHFROGRAnKZN AN C - PROGRAMME UND ANSCHLUSS VON C - FUNKTIONEN AN ANDERE PROGRAMME Beim Anschluß in beiden Richtungen muß die richtige Paraineterübergabe beachtet werden. Funktionen ohne Parameter werden mit einem Assembler CALL aufgerufen und kehren mit RET zurück. Der Speicher hJjiter dem Stackpointsr wird als frei angesehen. Aktuelle ParaErter werden im Stack übergeben und dürfen vom aufgerufenen Programm verändert werden. Diese Änderung hat keine Auswirkung auf das aufrufende Programm. (Um dort Werte zu verändern können Pointer verwendet werden.) Sei definiert: int vi, vj; long vl; double vd; Die Funktion fu findet den Stack nach dem Aufruf fu(vi,vl,VQ/vi); wie folgt vor: S? --> | Rückkehradresse 1 vi v 1 1 ( low) (high) I | vd (low) 1 vd | vd 1 vd (high) v 1 i i tt 1 • • •• Auf den Parameter vj kann wie folgt zugegri.-fen werden, wenn seit tlntrt in die Funktion der Stackpointer nicht verändert wurde: 4.4- IC LXI K , 1 6 - DAD SP MOV E,n INX H MOV D,M Die Funktion fu kann mit einem Assembler RET zurückkerirrn. Die Parameter werden vom aufrufenden Procramm vom Stack eitfernt. Dir Rscister sowie die •P* ^ Parameter dürfen verändert sein. Parameter vom Typ char werden nach int gewaidelt und selche vom Typ float nach double, bevor sie auf den Stack gebracht werden. Seispiel für die Ausgabe* des Zeichens ? vor eir.em Asseablerprograinm aus mittels der Funktion PUTCHAR: LXI PUSH CALL PO? H/?' H PUTCHAR H Ein Für. Jet ionswert kann abhängig vom Typ d<:r runJction zurucxgeliefert werden. Typ double long sonst Ort 8 Byte ab der Adresoe CFPHIfl die beiden höherwe-rtigen Byte ab der Adresse CLPRIK und die beiden niederwertigen Byte im HL Register im KL Register Auf externe nicht statte deklarierte C - Cbje.cte kann mittels des Namens zuaeoriffen werden. (z.B. wie oben auf die Funktion PUTCKAR) W I . SYSTErtGRCSSEN Is gelten folgende Begrenzungen: - die Lange der C - Quelle ist unbegrenzt - die Lange der Ausgabe wird nur durch die maximal zulässige Dateigröße eingeschränkt «* - maximal 300 verschiedene externe Symbole (z.B. Variablen,Felder, Funktionen) in eines Program m teil gleichzeitig (im ganzen Programm unbegrenzt) - maximal 60 aktive lokale Symbole (d.h. in einer Verschachtelung von Blöcken) pro Funktion - maximal 50 verschiedene externs Strakturdefinitionen in einem Programmier! - maximal 25 verschiedene aktive, lokale Strukturdefinitionen pro Funktion - maximal 259 ^acrodefinitionen (£define) ii einem Programmteil - maximal 80 Zeichen für alle Parameter ii einem Macroaufruf mit Parametern - Anzahl der Parameter bei einem Funktionsaufruf: maximal 40 - maximale Zeilenlange 159 Zeichen - Schachtelur.gstiefe von Blocken: 40 - Schachtelungstiefe von while, do .. while, for, switch (auch gemischt) 33 - maximale Anzahl von Marken bzw. goto zu noch nicht definierter I^arke 50 pro Funktion - maximal 14 Hodifikatoren pro definiertem Objekt (z.B. ( » » « * * » ( » f u ) ( ) ) C K ] C 3 C D C 3 C 3 ) wenn nicht ausreichend Speicherplatz vorhanden ist, können eventuell nicht alle Uerte gleichzeitig ausgeschöpft werden. Hei besonderen Erfordernissen kann eine Änderung dieser Größen vorgenommen werden. HAEDUAEE UMD SOFTWARE VORAUSSETZUNGEN Es wird ein 3 0 8 0 . 6 0 8 5 oder Z80 -Rechner mit einem CP/M System (Version 1.4 oder höher) benötigt. Der Arbeitsspeicher muß von Adresse TPA = 100H bis BDOS frei benutzbar sein. Der Compiler benötigt in der Version 3.18 mindestens 50k Speicher (d.h. ein 56k C P / M System). Für große Programme wird D ehr Speicher benötigt. Ein 60k CP/M System ist empfehlenswert. Ist weniger Speicher vorhanden, kann auf Anfrage auch eine SpezialVersion bezogen werden. Außerdem wird ein Assembler benötigt, wobei der zum CP/M System mitgelieferte ASM.COn ausreicht. Ein Assembler mr: Linker (speziell MAC80 / L80 vor. Microsoft) erleichtert die Handhabung, besonders, wenn Programme in zehrere Teile aufgeteilt werden. Durch eine Option wird dem Compiler mitgeteilt, mit welcher der beiden Asse~bierarten aearbeitet wird. -r (| K . FEHLERMELDUNGEN I . FEHLERMELDUNGEN DES COMPILERS Wenn vom Compiler ein Fehler oder ein Mangel entdeckt wird, gibt er eine Fehlermeldung aus. Die Stelle, an der der Fehler bemerkt wird, ist durch ein " unter der Quellzeile, die auch ausgegeben wird, markiert. Es können natürlich nur syntaktische Fehler entdeckt werden, und keine Fehler, die in der Logik des Programms ihre Ursache haben Es gilt die Regel: Das Fehlen von (, ), C, 3, ; und : bei beiiingten Ausdrücken wird in 'eindeutigen' Fällen korrigiert. Alle arideren Fehler wsrdea in keinem Fall vcin Compiler korrigiert. Eine typische Meldung ist folgende: fcr (i =0 i < 5 ; -H-i) f u n k ( i ) ; A Zeile: 5 \ SEMIKOLON FEHLT *«**«* Dieser Fehler wird vom Compiler korrigiert, wie auch das Fehlen der beiden zum fcr gehörenden Klammern korrigiert würde, aber es wird ausdrücklich geraten, falls Fehler aufgetaucht sind, dies= in der Quelle zu korrigieren und neu zu übersetzen. Eine Fehlermeldung kam nämlich zu falschen Schlüsser, verleiten, und das erzeugte Programm ist dann falsch. Sei z.B. folgenies ein vollständiger Prcgrammteil: Dutstr(ptr) char -Dtr; { while (*ptr) PUTCHAK(*ptr++); nz() (~?U7CHAR('\r'); PU7CHAR('\N'); > Folgende Fehlermeldung erscheint. :;nz() ( PUTCHAH('\r'): PUTCHAR('\N') ; } » s*. ;»«**«Zeile: 2 SEMIKOLON FEHLT »*»**» Der eigentliche Fehler ist hier nicht das Fehlen eines ' sondern die vergessene } ,üe die Funktion outstr am Ende d-?r ersten Zeile abschließt. Ein solcher Fehler läßt sich nur korrigieren, wenn man weiß, was das Programm in dieser Stelle leisten soll. A?, diesem Seispiel kann 'man auch sehen, daß ein Fehler Folgefehlermeldunren nach sich zieht. Am Ende des Programms wird bemerkt, daß zu einer { iie zugehörige } fehlt, und der Compiler meldet 'das Fehlen einer } . Z.T. folgenden sind die Fehlermeldungen des Compilers aufgelistet und acglieft s Ursachen a n e e b e n . "ANZAHL PARAH. FALSCH" "URONG NUM3ER ARGS" Bei der Definition einer Funktion stimnen Paraaeteriiste und zuaehö'rige Parciueterdefinitionen nicftt überein. "AUSGASEDATEI EROEFFNEN NICHT MOEGLICH" "GPEN FAILURE" , Die Diskette ist voll, oder ein Schrei-bschutz ist gesetzt. uöclicfts Fenlerursacne: Die Diskette ist voll oder defekt. "DEKL. FEHLT* "DECL. KISSING' Fehlerhafte Strukrjrc-efinition. Vielleicht wjrde der Naae einer Vari ablen vergessen. "DEKLARATION ZU KOKPLEX" "DECI^.P-ATION TOO COKPLEX" f Siehe Abschnitt Systesgrcßen "EP.OEFFNE^J .LST NICHT iICEGLICH" "GiiVT OPEN .LSr Die Diskette ist voll, oder ein Scftreirschutz ist gesetzt. "~\; <z.r~~ F-KRO-APGUF^MT"' * * i. —^ h» V—« * • JM* l « * * *Vi k W / 4 A • >_^ W 4 * ^^ * U A 4^ l Die Pörameterliste eines Kakroaufrufes ist fehlerhaft. "FALSCHER AUSDRUCK" "INVALID EXPRESSION" i i | | In einem Ausdruck wird an dieser Stelle ein üane oder eine Konstante erwartet. |j ii i * II f .".L— •_." ür? ?r*.nAnii i: ' ••» "r"-.^»*-"* IT " C "* M£" r pC"^ 'i Eine Funktion, StruJctur oder Union ist als Parameter einer Funktion in C nicht zulässig, (üohl Pointer darauf) 3 "FALSCHER SYMBOLNAriE11 "ILLEGAL SYMBOL NAHET1 • i' ü 'i^ i| i j} ' An dieser Stelle wird zwingend ein Name erwartet. z.B. int -J-i; "FLOA7 FALSCH" "UROrJG FLCAT 1 ' ' Es liegt eine fehlerhafte Gleitkonimakonstante vor. • ...<?2^"''3r- j'• 'i ••-«** •r.'«---xr-v '. • • --". "^ ' - : *= •..- * •—. - • • '...' • - fr T : ][ • •*^?-ZK!^-f. S^Ä-C^?^-—^•^ ^' ' ^'•••• '«—".'-•--' " F U N K T I O N GEFORDERT' "MüST BE FUNCTION" Nur auf einen Ausdruck vom Typ Funktion darf eine Parameter liste folgen. Möglicherweise wurde in einem Ausdruck ein Operator vergesssen: 2.3. in A * (b -p c); der Operator « "FUNKTION NICKT ERLAUBT' "FUNCTION NOT ALLOUED" Hier ist die Definition einer Funktion nicht erlaubt. z.B. innerhalb einer Struktur kann keine Funktion def juert werden. Vielleicht fehlen Klammern, u in einen Pointer auf eine runktion zu definieren, was erlaubt ist: int ( * fu) (); , "FUuKTIOXSOEF VERBOTEN" ' 1 "FUNCTICN-CEF NOT ALLOU27 In einer externen Definition kann, wenn nicht vorher das Schlüsselwort extern steht, nach , keine Funktion sdef i nition vorkommen. z.B. static int i , f u n k ( ) ; ist als externe Definition nicht erlaubt. "#Ir FEHLT 1 "MissiKG *:r- Es tauznt #eise oder ^endif auf ohne z u e h ö r i e s #if. :rT :r -^r L " < . _ l>:rLUD~J. JX^— l_r w.w' _ • ~.L*i-~ Selbst er klärend INDIREKTION" Der mcnadische Operator » nicht von Typ Pein t er ist. wird auf einen Ausdruck angewandt, der "IMDIZIERUNG VERBOTEN" "GAN' T SUBSCRIPT' Nur ein Ausdruck vom Typ Pointer oder Feld kann rr.it C..] indiziert sein. "INJ7. NICHT ERLAUBT 1 "INI T NOT ALLOUED" Objekte wie z.B. Funktionen können ni:ht mit einen Wen vorbesetzt (initialisiert) werden. i "LMIT. U N I O N VERBOTEH" "T Vxl»M .4 ' T • TM ^ . i «T ^ .T ^. T< ^T>M\ XTWO1f»" 1 Eine union kann nicht initialisiert werde.i. "KEIN FUNKTICNENFELD" NO ARRAY CF FUNC7IOiT •t * In C gut es kein Feld dessen Element« Funktionen sind. (Pointer auf Funktionen sind zulässig.) i fll - C K 4 Feh i=r7i° lau::" "KEIN PARAttETERNAME" "EXPECTED ARGUMENT' Bei einer Funktionsdefinition taucht b<?i der Parameterdefinition ein Nase auf, der nicht in der Paranieterliste erschienen ist. * "KEIN PLATZ FUEH STRINGS" "NO STRING SPACE" Der Platz für Stringkonstante ( " ") innerhalb der gerade bearbeiteten Funktion ist verbraucht. Abhilfe: Hilfsfunktionen oder Initialisieren von Feldern oder Pointern mit den Strings. Siehe auch Abschnitt Sy Steingrößen. ' "KEIN PLATZ: DEKL." ••NO SPACE: DECL." Es ist zu wenig Speicherplatz vorhanden. Abhilfe: Das Programm wird in mehrere Teile aufgeteilt und diess getrennt con-piliert. Siehe auch Abschnitt Systesgrößen "KEIM PLATZ: LOYALE DEXL." r > r M : - ti^'ir-v cT3*i ""C" rLOLrxL r*< ~ ~* r PIC"I^T .JO brnLü.. UtLL. •j Es ist zu wenig Speicherplatz vorhander. Eventuelle Abhilfe durch die Verwendung externer Variablen oder H..lfsfunktionen möglich. Siehe auch Abschnitt Systengrößen ' ; i ; i "KEIN PLATZ: LOKALE s/u DEKL." M NO SPACE: LOCAL s/u DECL." Es ist zu wenig Speicherplatz vorhanden. Eventuelle .Abhilfe durch die Verwendung externer Variablen oder HilfsfunJctionen möglich. Siehe auch Abschnitt Systencro'ßen "KEIN PLATZ: s/u DEKL." "NO SPACE: s/u DECL." Es ist zu wenig Speicherplatz vorhanden. Abhilfe: Das Programm wird in aehrere Teile aufgeteilt und diese getrennt compiliert. Siehe auch Abschnitt Systemgrößt?n « "KEIN STRUCT/UNICN VAE-NAME" "NO STRUCT/UN10N VAR-N>J*E" Nach einera . oder -> wird ein Naae aus der zugehörigen Struktur def inition erwartet. " K E I N E AKTIVE SCHLEIFE" "NO OPEN LOOP1 r ontlnue darf nur innerhalb einer Schleif-? benutzt werden. L-U i "KEINE AKTIVEN SCHLEIFEN/SUITCH" "NO ACTIVE LOOPS/SWITCH" . a . break darf nur innerhalb einer Schleife/switch benutzt werden, •, i Ü. HI - C K 5 rehl5iv,--:ü-j..- "KEINE FELDFUNKTION" "NO ARRAY FuNCTION" In C gibt ss keine Funktion die als Funktioniert ein Feld zurückliefert. (Pcinter sind zulässig.) "KEINE FUNKTIONS-FUNKTION" "NO FJNCTION FUNCTION" ' " Ir. C gibt es keine Funktion die als Funktionswert eine Funktion zurückliefsrt. (Pointer auf Funktionen sini zulässig.) "KEINE STEUCT/UNION FUNKTION" "NO STRUCT/UNION FUNCTION11 In C gut es keine Funktion die als Funktionswert eme Struktur oder Union zurücklie fert. (?oir.t=r darauf sini zulässig.) ir \ f VT 1" * K i__. J » .~ it l^i li -_ > .^ i' IV h * *i > — " —. (—i - Die Art der Klanzer wird nit ausgegeben. Die eigentliche- Fehlerursiehe kann insbesondere bei geschweiften Klaansrn an einer anderen Stelle als der oeseldeten lisaen. -* ^ 1 ^RUi-TrT ~~ i i *** * • • i A •« • i i '-V'JS — /~^» •% "-^. _ "-t - t " J , ' /-r^ *»»*•» »i LJiiALTV Die ParaiTiStsrlists oder Paraneterdefinitionsn bei einer FurAiionsdefinition sind fehlerhaft. "LASEL NOT DEFINED" Diese Fehlermeldung erscheint am Ende einer Funktion, wenn eine SprjngFiarkr, die bei einem goto aufgeireten ist, nicht ii^ierhaib der Funktion als Marke vorgekommen ist. Der betreffende Name wird in der Meldung mitangegeben. "LAENGE FEHLT" "LENGTH MISSING" In der Definition eines mehrdimensionalen Feldes fehlt die Lä.-gsnangabe in einer anderen als der ersten Dimension. (Fehlt sie in der ersten Dimension, so wird automatisch ein Pointur definiert.) "MAKRO TAB. VOLL" "MACHO TA3LE FÜLL" " : Es ist zu wenig Speicherplatz vorhanden. Abhilfe: Das Programm wird in mehrere Teile aufgeteilt und diese getrennt compiliert. Siehe auch Abschnitt Systemgrößen. "MARKE FEHLT1 "MUST 3E LABEL" Nach goto fehlt die Sprungmarke. j j : ."v b r en "MUS5 FUNKTION SEIN" "MUST BE FUNCTION" Befindet man sich außerhalb von Funktionen, so icuß eine externe Definition ohne Speicherklasse und Typ IM einer Funktionsdefinition gehören und auf den definierten Namen eine ( folgen. Diese Meldung erscheint z.B. auch wenn ein Typ falsch geschrieben wurde wie isnt statt int. "MUSS GANZZAHLIG SEIN" "MUST BE INTEGRAL" Manche Operatcren wie bitweises und, oder, exklusives oder erfordern als Operanden Ausdrücke von ganzzahligem Typ. "MUSS KONSTANT SEIN" "MUST BE CONSTANT 1 '-, An einigen Steilen dürfen nur konstante Ausdrücke auf Treten. (£i£, Länge in Felddefiniticnen, case, Initialisierung). Die Adresse eirer temporären Variablen ist keine Konstinte. Siehe auch C Sprachbeschreibung. "MUSS LVALUE SEIN" "MUST B E LVALUE" " , f An verschiedenen Steilen (z.B. links von' einem Gleichheitszeichen) kann nur eir, Ausdruck, der ein Ivalue ist, auftreten. Ein Feldname z.B. ist kein Ivalue. "M! ilUSS TYP SEIN" "MUST BE TYPE" In einer Definition wird ein Typ oder ein typedef - Mane erwartet. Eventuell liegt ein Rechtschreibfehler vor. "NEGATIVE LAENGS" "NEGATIVE SIZE" Die Länge eines Feldes darf nicht negativ sein. " OPTION A" Unter der Option A ist die Initialisierung von internen statischen Variablen nicht erlaubt. Mögliche Abhilfe: Verwendung von exter-en statischen Variablen. Außerdem müssen unter der Option A statische Funktionen vor des ersten Auftreten deklariert werden. « "REFLEXIV S/U -MUSS POINTER SEIN" "REFLEXIV S/U -MUST BE POINTER" Innerhalb eir.er Struktur- oder Union D»finiticn darf die gerade definierte Struktur oder Union nicht noch einmal auftauchen sondern nur ein Pointer darauf. "SCHON DEFINIER?' "ALREADY DEFINED 11 In der Meldur.g folgt der Nase, der bereits an anderer Steile definiert wurde. nl - C r 5h i = ."-n- '. .;•:. K 7 "SEMIKOLON FEHLT' "MISSING SEMICOLGN" Es wird ein Semikolon erwartet als Ine s einer Anweisung oder in for Anweisungen. "STACK UEBERLAUF ERUARTEr "STACK OVEHFLOU EXPECTED" Es ist zu wenig Speicherplatz vorhanden. Der Stack läuft möglicherweise während der weiteren Bearbeitung der Anweisung in die Tabelle cer lokalen Symbole über. Das erzeugte Programm kann fehlerhaft werden. Treten keine weiteren Fehleraelcuigen auf, so kann, nach Prüfung der Assemblerdatei an dieser Stelle, cias AsssmblerprograEinm weiterverwandt werden. "STHUCT/üNICN FALSCH" 5THUCT/UNION" ! Fehlerhafte Definition einer Struktur oder Union. i v lu' !TiUTL /~^i // IU*» T>T TP,V n u.U;\ TTM Jüiir^ Eine Strukturdefinition darf nicht leer s;ein« "STRÜCT/UNION NOETIG" "MUST BE STHUCT/UNICrr . oder -> kann nur auf einen Ausdruck vom Typ Struktur angewandt werden. "TYP FALSCH" "URCNG TYPE" Es liegt kein zulässiger Typ vor. Typumwandlung oder bei sizeof z. F. Bei einer Definition, einer "TYP UNVEREINBAR" "TYPE MISMATCH" Zwei Typen sind nicht miteinander vertraglich. z.B. wird eine Variable einmal als extern int var; ein anderes Mal als extern long var; erklärt. Oder: in einem bedingten Ausdruck sind die beiden möglichen Ergebnisse Pointer von verschiedenem Typ. "UE3ERLAUF GLOBALE SYM30LTAB." "GLOBAL SYMBOL TA3LE OVERFLOW Es wurden zu viele externe Namen defir^ert. Abhilfe: Das Programm wird in mehrere Teile aufgeteilt und di£-ss getrennt compiliert. Siehe auch Abschnitt Svstemorößen i "UEBEHL^UF LOKALE SY7I30LTA3." "LCCAL SYMBOL TA3LE OVEHFLOU" Es wurden zu viele lokale Variablen et:. in einem Nest von Blöcken innerhalb einer Funktion deklariert. Evenruelle Abhilfe durch die Verwendung externer Variablen oder Hilfsfunktionen möglich. Siehe auch Abschnitt SystemgröDen i L S n. - C K 8 "ÜIXEFINIERTER NAME" "UMDEFINED IDENTIFIEH" Ein Nai2e taucht auf, ohne vorher definiert worden zu sein. "U'KILE FEHLT' "MISSING UHILET 1 Nach do fehlt das zugehörige while; . Eventuell wurde vergessen { } us die von do und uhile eingeschlossenen Anweisungen zu setzen. "ZEILE ZU LANG1' ••r TM r T'OO r Siehe Abschnitt Sy Steingrößen r>/ r>Wj. iLn i Siehe Abschnitt Sy Stellgrößen "7JjTL-,TVT~r r ^^i^-w^-V-.v.— er r\-r-ir~' V ^--«. ^^ Ä »-rf- ^ v r \r r r™^ r »^ T ^^» i j M-.N: LETV c.LS •*. ' Die Schachteiungstiefe bei Blöcken ist zu groß. Siehe auch .Abschnitt S y st es großen i v > VV : ~-..!\ I Siehe Abschnitt Systemgrößen "ZU VIELE r*.AKHOSM "TCO ilANY MACRCS" Es wurden zu viele Makros definiert (r^efine). Abhilfe: D-as Programin wird in iDehrere Teile aufgeteilt und diese getrennt comrilien. Siehe auch Abschnitt Sy st ea großen. > i "ZU\ r IELE PARAMETER" "700 KANY PARAMETERS' ^< Ein Funktior.saufraf Systesgrcßen. hat zu viele Panneter. Siehe auch Abschnitt ] "ZUVIELE REFLEXIVE S/U POINTEH" "700 nANY REFLEXIV S/U POINTERS1 In einer Strukturdefinition tauchen zu viele Pointer auf eine Stru)ctur vom gerade definierten Typ auf. "" FEHLT1 "NO QUOTE" Ein String ist nicht richtig abgeschlossen. Möglicherweise sind dadurch nachfolgende Anweisungen nit in dsr. String hineinger.oEir.en worden. '" FEHLT" ":iO APOSTROPHE" Eine Zeichenkonstante ist nicht richtig ai-geschlossen. MI - C K 9 ch 1 . ,-l "& OHNE LVALUE" "ILLEGAL ADHES5" Der nionadische Operator « wird auf i.-inen Ausdruck, der kein Ivalue ist, angswcndt. Siehe C SpracnbeschrelDung. K 1Ü c — TI o t ^ 11 ~ I I . LVoTZEITFEHLERKELDUNGEN wahrend des Laufes eines Progranmes konne.i die folgenden Fehlermeldungen a in Terminal auftreten: "C - DIVISION" wenn eine Division durch 0 festgestellt wird, bricht das Programm ab. "OVERFLOW" Wenn eine Gleitkommazahl bei einer arithmetischen Operation oder beim Hunden dein Betrage nach größer als die größte zulassige Gieitkominazahl wird, erscheint diese Meldungen ajf dein Terminal. Das Programm wird fortgeführt, und es wird die bet:agsmä£ig größte positive oder negative Zahl eingesetzt. "UIÖEHFLOW" "Wenn eine Gleitkommazahl bei einer arithmetischen Operation oder beim Runden des Betrage nach kleiner als dis kleinste zulassige Gieitkommazahl wird, erscheint diese Meldungen auf dem Terminal. Das Programm wird fortgeführt, •* * und es wird die Zahl Ü.O eingesetzt. -^ "STACK OVERFLOW Wenn nicnt mehr ausreichend Speicherplatz auf dem Stack zur Verfüc/ung steht, wird das Programm abger.roc.ien. Der Stack wird für Funktioasäufrufe und lokale Variable benutzt. Nach u zten wird er durch die Prcgrammgröße ur.d den von der Speiche::platzv~:-waltung zur Verfügung gestellten Speicher begrenzt. Die Reaktion auf einen Laufzeitfehler kann vom Benutzer geändert werden. Dazu müssen die entsprechenden Eiblioihek:;progranDe CCODIV, CLCDIV, CFQDIV, CFOVEHFLOU oder CFüNDEHFLOW geändert werden. n l! ! Weitere Unterstützung (wie Bearbeitung von Fehlermeldungen oder der Bezug von Ergänzungen) wird nur gewahrt, wenn Sie die untenstehende Mitteilung an die zeigende Adresse senden: Herbert Rose Bogenstr. 32 •4390 GladbecJc . l Ich / U'ir habe(n) den C - Compiler MI - C bezogen. emr-nsnumDer und Kennunz-er Irres Conciler bezogen am: bei: chu/or -.v. r~ *•* ^ ~* * * * i /"*\ ^"s *T* : * * *"* ^ ^™ *" ** *~ *-~ A •' ' — .J • n _ *• * • *v v_ J * «. v'T * >-*' ^j / •• ^' M k M Abbruch des Compilerlaufes abgeleiteter Typ C 8 ASS D 17* A5SD ASSL A l D 17 D 17 abstrakter Deklarator C 22 additive Opsratorsn C 23 ändern der Zeilennuaner C 44 Änderung der Coapiiation siehe Option Anweisungen C 28 - C 38 Anweisungen a." den Presrocesscr AHCTAN C 42 D nthsetische U E Wandlungen C 13 array C 14, C 15 - Initialisierung C 18, C 19, E l F^SID ... #enc5asin ATOL 3 2, C 44, E l B 2. C 44 D IG D 18 D 17 C C 20 Au=drucXiiste C 20 Ausdrucke Ausdrücke mit Operatoren ÄUto C 10/C 18 ED05 C 21 A 2, D 13 edingie Anweisung C 28 edingte Compilation C 43 u edingter Operator C 25, 2 26 Bibliothek A 2, B 7, D l - D 18 iitfeider in Strukturen E l uweise Operatoren C 24 leck 'c 38 lockanweisung C 38 K *»> X eak C 32, C 33, C 34, Z 35 CALLOC c^se cast Cr?RIK CrHEE CHAIN D 13 C 27, C 31 C 21 B 2, H 2 D 18 D 13 cl-ar B 2, C 13, F l, G CHHRDY CLCSE CLCSAL C1PHIH D l D 6 D 13 B 2, H 2 Co~pilerläuf, Abbruch A E l Ancsr^ng der siehe Option - bei Prosit nur Linker 3 4 - 5 5 - bei Arbeit chne Linker B 5 - 3 7 - von mehreren rusarisengencngen Dateien c?r.tiniie C 35 D 19 C05 CHEAT D 5 (externe) ce fault C 31 p-iefir.e C 42, I l lefinitionen C 10 leklaraticnen C 8 C 39 -, abstrakter C 22 dezimale Konstante C 3 o -t r> dvacische de 13, I C~erctoren , l, G l, H 2 C 2 - C 27 • »* «Z*- *^*^T^ ^T^^ p* ^ —* •-% i-* ^ *» •** ^ ^ ^»''^ "^ Z^T ----uu-Ii VGI1 .-.5r: = ^.*/I6i LcXk-s /*^ L 28 C 43 44, E l 30 C 44 Irsatzdarsteilungen von nicht darstellbaren Zeichen Irsetzunoen (vcn Makros) C 42 EXIT " D 13 _r>:n D 13 ZA? ZA? 10 D 13 D 19 extern =:cerne externe e:nerr.e e:-terne FILOSE C 4 C 10, C 39, H 2, I l Datendefinition C 39 Definitionen C 39 Funktionen C 40, I l Objekte C 10, C 39, G I l D 3 Fer.ieriüeldungen A l, 3 l, K l - K 10 Feld (array) C 14, C 15, E l - Initialisierung C 18, C 19, E l Feldlange C 14, C 19, C 24 F3ETS D 3 flrat A l, C 13, E l, F l, G l f l r a t Konstante F:?EN D2 f:r C 33, G l FFHINTF D 12 FPUTS D 3 C 5 3 5, 3 G MI - C 5 3 FHEAD 7SC.-XF FSEIK D 4 D 12 D 4 Fun.-r:ion A l, B l Funden sdefinition C 40 ^U r-— r ,i— c r^/•*__ v a r -I_LL. » m»,c r s_^ -r kü.-« —C-l* « w FwEITE T \^ 9 J^ T \^ 40 «t \J D 4 c/am: ihlige Konstante C 3 Galt: ;gsz>ersich von Objekten GETC D 3 GET: ^^ r»*^" •AH G ±..- oto C 4G D l D 2 aKl A l, C 13, E l, F l Kcnstarke C 5 Objekte A 2, C 10 C 32, C 33, C34, C 37, I l C 3 1O 28 - C 30, G C 27, C 43 C 43 C 43 C 42, E 1 D 15 isisrung C *l So C 19. C 27 C 3, C 13, F . H 2 int int .'rr.stante C 3 inter zr Objekte C 10, C 11 Inter T A 2 I5AL:; JM D 16 ISAL ?HA D 16 ISLC^E- iss? A:: -^ r—t »— ^ —» i b U r r ij •^ i^^\ * ^. i u f. D D 6 D D D D D 17 16 16 16 16 16 Komsi:perator C 26 KonjZr-tare A l, 3 l, C 7 Konstinte C 3 :<onsTz_-:er Ausirjck C 18, C 27 C 37, I i labsl C * * i • Lauf z ritf ehlsriaeldungen 1 osrs Anweisung ir.rioi mnrr ' leere 33 #Iine C 44 LN D 19 K 10 5 11 crtwor t i S 4 ±31 LOG D 19 logische Cperatcrsn C 24, C 25 lor.g C 3, C 13, F l, G l, H 2 lc-.-g Konstanten C 3 LSEIK D 6 Lvalue C 20 sain 3 l, C 41 KÄLLOC D 18 scr-adische Operatoren Bültipiikative Operatoren M a T~ CD '~ C 21, C 27 C 23 C l Oir-eJcts C 10 - C 12 CKiale KoriStai-ts C 3 0?ZN D 5 Cperatoren C 21 - C 26 Option A 1; 3 l, 3 2 Option 5 3 2, G l ?ar» Beter Pcinter ?OT C 8, C 40, I l C H l . C 8, C 14, C I G , D 19 ^"^^ ^ *^ -^ ^ ^ ^ ^ — « ^^ »r^ivLcjiÜj. r prin-ärs Ausirjcks FHINTF D 10 PUTC D 4 PU7CHAE D l PUTLST D 2 PUTS D l READ return 3EUIND ?.I>Z)EX 5CANF 5==X C 20 D 6 C 32, C 33, C 34, C 36 D 6 D 15 D 7 D 18 ScrJ.ü559iworts s^ift Operatoren sücrt C 13 SIN D 19 r^zsof C 21 Speicher Jciasse C 2 C 23 C 10 - C 12, C 39, G l SPHINTF D 12 SQRT D 19 SSCANF D 12 static C 10, C 11, G l statische Objekte C 10, Cll. G l STRCAT D. l4 25, Z 5 5 STRCMP 5TRCPY St D 14 D 14 String C 6, C 19, B 2 Stringfunktionen D 14 STRLEN STRNCA STRNG1P STRNCPY STRSAVE D 14 D 14 D 14 D 14 D 14 C 16, E l, I l C 16, E l, I l B 2, C 31, E l, G l struct Struktur switch TAN D 19 temporäre Objekte Trace A l, B l, Trennungszeichen TOLOUER D 16 • TOUPPER D 16 typ C 8, C 9, C typedef C 11 tYD-name C 22 C C IC, G l B 3 C 7 10, C 13 21, G l Umwandlungen (arithmetische) =undef C 42 UNGETC ÜNGETCHAR union ÜNLINK unsigned C 13 D 3 D l C 17 D 13 C 3, C 13, F l i Veränderung der Corapilation Vergleichsoperatoren C 24 Vorbesetzung C 18 while siehe Option C 32, G l D 5 Zahlendarstellung A l, F l Zeichenkonstante C 4 Zeichen, nicht darstellbare Zeilennummer ändern C 44 Zuweisungsoperatoren C 25 ii C 4 ii l K. -v. "c, . «v •• JL " E» l t» -v- v x" o --i i« * -*?. \\:- . "t
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
advertisement