home *** CD-ROM | disk | FTP | other *** search
- TURBO C++: ANTWORTEN AUF ALLGEMEINE FRAGEN
-
-
- I n s t a l l a t i o n u n d S t a r t
- ----------------------------------------------------------------------
- F. Wie wird Turbo C++ auf meinem System installiert?
- A. Legen Sie die Diskette 1 ("INSTALL") in das Laufwerk A:
- Ihres Computers, setzen Sie dieses Laufwerk mit dem Befehl
-
- A: <RETURN>
-
- auf der DOS-Kommandoebene als Standard, und geben Sie dann den
- Befehl
-
- INSTALL <RETURN>
-
- ein. INSTALL fragt nun als erstes, von welchem Disketten-
- laufwerk die Dateien gelesen werden sollen. Tippen Sie
-
- A: <RETURN>
-
- Als nächstes erscheint nun das Menüsystem von INSTALL. Folgen Sie
- den Anweisungen.
-
- F. Wie wird Turbo C++ nach der Installation gestartet?
- A. Geben Sie auf der DOS-Kommandoebene
-
- TC <RETURN>
-
- ein, nachdem Sie Turbo C++ installiert haben.
- Das Handbuch Einführung (Kapitel 2 des Benutzerhandbuchs) zeigt
- schrittweise, wie es von diesem Punkt an weitergeht.
-
- F. Wo liegen die Unterschiede zwischen TC.EXE und TCC.EXE?
- A. Das Turbo C++ Programmierpaket enthält zwei voneinander unabhängige
- Compiler: die integrierte Entwicklungsumgebung (TC.EXE) und die
- Kommandozeilen-Version TCC.EXE.
- Bei ersterer handelt es sich um einen "Programmverbund" aus
- Compiler, Editor, Debugger, kontextbezogener Hilfestellung usw., wobei
- die einzelnen Funktionen über ein Menüsystem miteinander verbunden sind;
- bei zweiterem um einen reinen Compiler, der durch die Eingabe
- einer Kommandozeile (von der DOS-Kommandoebene aus) gestartet wird
- und während der Bearbeitung eines C-Quelltextes keine weitere
- Interaktion mit dem Benutzer ausführt.
-
- F. Was ist eine "Konfigurationsdatei"?
- A. Über eine Konfigurationsdatei wird Turbo C++ mitgeteilt, welche
- Einstellungen (Compiler-Schalter, Optionen usw.) als Standard ver-
- wendet werden sollen und in welchen Directories sich Include-
- Dateien bzw. Bibliotheken befinden.
- TC.EXE - die integrierte Entwicklungsumgebung - sucht beim
- Start nach einer Datei namens TCCONFIG.TC; TCC.EXE - die
- Kommandozeilen-Version des Compilers - nach einer Datei namens
- TURBOC.CFG.
-
- F. Wie werden Konfigurationsdateien erzeugt?
- A. Von der integrierten Entwicklungsumgebung aus: durch die
- Auswahl von Options/Save options. Turbo C++ speichert hier
- sämtliche Daten, die von den durch Borland gesetzten
- Vorgaben abweichen, in einer Datei, die standardmäßig
- den Namen TCCONFIG.TC trägt.
- Für die Kommandozeilen-Version: entweder durch
- Konvertierung der Datei TCCONFIG.TC mit dem Programm
- TCCONFIG.EXE (siehe Referenzhandbuch) oder durch die direkte
- Eingabe mit einem ASCII-Editor (siehe Referenzhandbuch, Anhang).
-
- I n t e g r i e r t e E n t w i c k l u n g s u m g e b u n g
- ----------------------------------------------------------------------
- F. Anscheinend findet Turbo C++ meine mit #include <...> angegebenen
- Dateien nicht. Wieso?
- A. Der Compiler sucht Include-Dateien in den Directories, die über
- Options/Directories/Include directories angegeben sind. Das Pro-
- gramm INSTALL trägt hier das Directory ein, in das auch die
- *.H-Dateien von den Originaldisketten kopiert wurden.
- Wenn Sie eigene Include-Dateien erstellen und diese Dateien
- in einem anderen Directory speichern, müssen Sie den Eintrag
- in O/D/Include directories entsprechend erweitern. Mehrere
- Einträge trennen Sie durch einen Strichpunkt ";".
-
- F. Ich erhalte die Meldung 'Linker error: Unable to open
- input file 'C0x.OBJ''. Wieso?
- A. Der Linker sucht den Startcode und die Laufzeitbibliotheken in den
- Directories, die über Options/Directories/Library directories an-
- gegeben sind. Das Programm INSTALL trägt hier das Directory ein,
- in das auch die *.LIB und *.OBJ-Dateien von den Originaldisketten
- kopiert wurden.
-
- F. Wie kriege ich den Compiler dazu, meine eigenen Bibliotheken anstelle
- der Standardbibliotheken einzubinden? Wie sieht es mit mehreren
- Quelltexten für ein Programm aus?
- A. Siehe Benutzerhandbuch, Kapitel 3.
-
- F. Der Linker beharrt darauf, Funktionen wie initgraph() nicht zu
- kennen. Wieso?
- A. Setzen Sie den Schalter Options/Linker/Graphics Library auf ON oder
- definieren Sie eine .PRJ-Datei, die graphics.lib explizit aufführt.
-
- F. Bei der Compilierung eines ganz gewöhnlichen Programms reagiert der
- Compiler auf die Zeile #include <stdio.h> mit der Meldung
- "Unable to open include file 'stdarg.h'".
- A. Aller Wahrscheinlichkeit nach wurde die Maximalzahl von Dateien
- überschritten, die DOS gleichzeitig offen halten kann. Fügen
- Sie Ihrer Datei CONFIG.SYS die Zeile
-
- FILES=20
-
- hinzu - danach reserviert DOS genügend Platz, um bis zu 20
- Dateien gleichzeitig bearbeiten zu können.
- ACHTUNG: Die Datei CONFIG.SYS wird nur beim Start des Systems
- ausgewertet - Sie müssen den Computer also neu starten, damit
- Ihre Änderungen wirksam werden.
-
- F. Die Farben der Menüs von Turbo C++ passen absolut nicht zu meinem
- Schreibtisch. Was tun?
- A. Benutzen Sie TCINST.EXE zur Verwirklichung Ihrer eigenen Vorstellungen.
-
- F. Wie kann ich einen Quelltext am einfachsten drucken?
- A. Aktivieren Sie den Editor von Turbo C++, laden Sie den Quelltext, und
- geben Sie den Tastenbefehl Ctrl-K-P ein. Dieser Befehl sendet entweder
- den momentan (mit Ctrl-K-B und Ctrl-K-K markierten) Block zum Drucker
- - oder, falls überhaupt kein Block markiert ist, die gesamte Datei.
-
- F. Beim Aufruf von MAKE, Run oder bei der Aktivierung des Debuggers
- übersetzt der Compiler manchmal verschiedene Teile meines Programms
- von neuem - obwohl die einzelnen Module wirklich bereits auf dem
- letzten Stand der Dinge sind.
- A. MAKE orientiert sich ausschließlich an Datum und Uhrzeit
- der einzelnen Dateien. Wenn Sie beispielsweise mit setfattr() expe-
- rimentiert und einem Ihrer Quelltexte ein "Zukunftsdatum" verpaßt
- haben, dann wird die entsprechende .OBJ-Datei für MAKE bis zum
- tatsächlichen Erreichen dieses Zeitpunkts immer "älter" sein.
- Diese und ähnliche Probleme lassen sich mit TOUCH lösen - einem
- Programm, das sämtlichen angegebenen Dateien die momentane System-
- zeit gibt.
-
- F. Warum funktionieren meine alten Turbo C++ Projekt-Dateien nicht mehr?
- A. Projekt-Dateien enthalten nun wesentlich mehr Informationen und werden
- deswegen nicht mehr im ASCII-Format gespeichert. Wenn Sie eine Projekt-
- Datei erzeugen möchten, wählen Sie die Option Project aus dem Hauptmenü
- und folgen den Menüs. Alte Projekt-Dateien können mit dem Hilfsprogramm
- PRJCNVT.EXE (in UTIL.DOC beschrieben) in das neue Format konvertiert
- werden.
-
- F. Warum wird meine Projekt-Datei automatisch geladen, wenn ich TC starte?
- Ich möchte eigentlich mit anderen Dateien arbeiten.
- A. Wenn sich nur eine Projekt-Datei im aktuellen Directory befindet,
- lädt Turbo C++ diese Datei bei jedem Start. Wenn sich keine oder mehrere
- Projekt-Dateien in diesem Directory befinden, wird keine automatisch
- geladen.
-
- F. Die rechte Maustaste ist nicht aktiv. Kann ich das ändern?
- A. Unter der Option Options/Environment/Mouse finden Sie ein Dialog-Fenster
- für die rechte Maustaste. Sie können sie damit beliebig umdefinieren.
-
- F. Wie bringe ich Turbo C++ dazu, Expanded oder Extended Memory zu benutzen?
- A. Benutzen Sie den Schalter /X für Extended und /E für Expanded Memory,
- wenn Sie Turbo C++ starten.
-
- F. Beim Compilieren bekomme ich den Fehler "Error: C:\TC\INCLUDE\STDIO.H:
- Overlays only supported in medium, large, and huge models
- Was ist los?
- A. Sie haben die Option Overlay Support ausgewählt, die nicht in den kleinen
- Speichermodellen tiny, small und medium funktioniert. Deaktivieren Sie
- die Option mit Options/Compiler/Code generation/Overlay Support
-
- F. Wenn ich nach dem Editieren einer Datei eine andere Datei laden will,
- bleibt die erste Datei auf dem Bildschirm. Wie kann ich sie entfernen?
- A. Schließen Sie mit Alt-F3 die aktuelle Datei. Mit F6 wechseln Sie
- zwischen Dateien.
-
- F. Beim Suchen/Ersetzen muß ich jede Änderung bestätigen, auch wenn ich
- Change All ausgewählt habe.
- A. Deaktivieren Sie die Option "Prompt on replace" auf der linken Seite des
- Dialog-Fensters.
-
- F. Wenn ich Pseudo-Register wie _AX verwende, erhalte ich beim Compilieren
- Meldungen wie "Undefined symbol '_AX' in function...". Warum?
- A. Pseudo-Register können nur im Turbo C++ und ANSI-Modus des Compilers
- verwendet werden. Die Option finden Sie unter Options/Compiler/
- Source menu.
-
- F. Wie kann ich, ohne eine Maus zu verwenden, Code zwischen Dateien
- kopieren?
- A. Markieren Sie den Block mit Ctrl-K-B (Anfangsmarke) und Ctrl-K-K
- (Endemarke), und benutzen Sie dann die Copy- und Paste-Befehle des
- Edit-Menüs. Sie können einen Block ebenso mit SHIFT-Pfeiltaste
- markieren.
-
- K o m m a n d o z e i l e n - V e r s i o n
- ----------------------------------------------------------------------
- F. Anscheinend findet Turbo C++ meine mit #include <...> angegebenen
- Dateien nicht. Wieso?
- A. Der Compiler sucht Include-Dateien in den Directories, die über
- den Parameter -I angegeben sind. Das Programm INSTALL erzeugt eine
- Konfigurationsdatei (TURBOC.CFG), die von TCC.EXE automatisch gelesen
- wird und in der das Directory eingetragen ist, in das auch die
- *.H-Dateien von den Originaldisketten kopiert wurden.
-
- F. Ich erhalte die Meldung "Linker error: Unable to open
- input file 'C0x.OBJ'". Wieso?
- A. Der Linker sucht den Startcode und die Laufzeitbibliotheken in den
- Directories, die über den Parameter -L der Konfigurationsdatei
- TURBOC.CFG angegeben sind. Das Programm INSTALL trägt hier das
- Directory ein, in das auch die *.LIB und *.OBJ-Dateien von den
- Originaldisketten kopiert wurden.
- Hinweis: Bei einem direkten Aufruf von TLINK müssen Sie den Such-
- weg für Bibliotheken und Startcode explizit angeben - TLINK liest
- die Konfigurationsdatei TURBOC.CFG nicht.
-
- F. Der Linker beharrt darauf, Funktionen wie initgraph() nicht zu
- kennen. Wieso?
- A. TCC sucht die Grafik-Bibliothek (graphics.lib) nur nach expliziter
- Anweisung ab. Zur Compilierung von BGIDEMO ist beispielsweise die
- folgende Kommandozeile notwendig:
-
- TCC BGIDEMO.C GRAPHICS.LIB <RETURN>
-
- Hinweis: Hier wurde vorausgesetzt, daß eine Konfigurationsdatei
- TURBOC.CFG mit den Suchwegen für Bibliotheksdateien existiert.
-
- E i n - u n d A u s g a b e
- ----------------------------------------------------------------------
- F. Die Befehle cprintf("Hello\n"); cprintf("world\n"); ergeben
-
- Hello
- world
-
- Woran liegt das?
- A. cprintf() arbeitet in dieser Version von Turbo C++ so, wie
- es eigentlich von Anfang an vorgesehen war - '\n' wird nicht
- (wie bei printf) in eine CR/LF-Kombination "übersetzt", sondern
- tatsächlich als einzelnes LF-Zeichen ausgegeben.
- Wenn Sie den Cursor nicht nur eine Zeile tiefer, sondern auch
- noch wieder in die Spalte 1 dieser Zeile setzen wollen, müssen Sie
- das CR-Zeichen beim Aufruf von cprintf() direkt angeben: Die Befehls-
- folge cprintf("Hello\n\r"); cprintf("world\n\r"); erzeugt das gewünschte
- Ergebnis (wobei es keine Rolle spielt, ob '\r' vor '\n' oder danach
- angegeben wird).
-
- F. Wie kann ich mit einem Programm Ausgaben auf dem Drucker erzeugen?
- A. Ab der Version 1.5 von Turbo C ist eine FILE-Variable namens stdprn
- in der Datei stdio.h definiert, die beim Start des Programms auto-
- matisch geöffnet wird. Ein Beispiel dazu:
-
- #include <stdio.h>
- main()
- {
- fprintf(stdprn, "Hello, world\n");
- }
-
- Die meisten Drucker arbeiten übrigens mit einer zeilenweisen Pufferung -
- tatsächlich gedruckt wird also erst nach dem abschließenden '\n'.
-
- F. Bei der Bearbeitung einer Binärdatei scheint sich Merkwürdiges zu tun,
- wenn die Werte 0x0D und 0x0A gelesen oder geschrieben werden. Was tun?
- A. Wahrscheinlich haben Sie die Datei ohne den Zusatz "b" geöffnet -
- die Routinen zur Dateibearbeitung gehen dann von einer Textdatei aus
- und übersetzen die Bytefolge 0x0D 0x0A als "CR/LF" in ein einzelnes LF beim
- Lesen bzw. erweitern den Wert 0x0A als "LF" auf eine CR/LF-Folge beim
- Schreiben.
- Öffnen Sie die Datei explizit im Binärmodus, wie es das folgende
- Beispiel zeigt:
-
- #include <stdio.h>
- main()
- {
- FILE *binary_fp;
- char buffer[100];
-
- binary_fp = fopen("MYFILE.BIN", "rb");
-
- fread(buffer, sizeof(char), 100, binary_fp);
-
- :
- }
-
- F. Wieso weigern sich printf() und puts(), farbige Zeichen zu erzeugen?
- A. Weil diese beiden Funktionen mit Standardattributen arbeiten. Für
- bunte Ausgaben und andere Spezialitäten des IBM PC sind die Routinen
- cprintf() und cputs() vorgesehen:
-
- #include <conio.h>
- main()
- {
- textcolor(BLUE);
- cprintf("Ich bin blau.");
- }
-
- F. Wie wird ein long-Wert mit printf ausgegeben?
- A. Mit "%ld":
-
- long int l = 70000L;
- printf("%ld", l);
-
- F. Wie wird ein Wert im Format long double (= Extended) ausgegeben?
- A. Mit "%Lf":
-
- long double ldbl = 1E500;
- printf("%Lf", ldbl);
-
- B e i s p i e l p r o g r a m m e
- ----------------------------------------------------------------------
- F. Wie wird BGIDEMO compiliert und gestartet?
- A. 1. Die folgenden Dateien müssen sich im momentan gesetzten Directory
- befinden:
-
- BGIDEMO.C
- *.BGI <- die Grafiktreiber
- *.CHR <- die Zeichensätze
-
- 2. Starten Sie TC mit dem Befehl
-
- TC bgidemo <RETURN>
-
- 3. Geben Sie den Tastenbefehl Ctrl-F9.
-
- F. Wie läßt sich mit Turbo C++ eine .COM-Datei erzeugen?
- A. Zusammen mit den DOS-Versionen bis (inklusive) 3.2 wird ein Programm
- namens EXE2BIN ("EXE to Binary") ausgeliefert, über das sich
- .EXE-Programme des Speichermodells TINY ins .COM-Format umwandeln
- lassen.
- Wenn Sie EXE2BIN nicht Ihr eigen nennen: der zur Kommandozeilen-
- Version von Turbo C++ gehörige Linker läßt sich bei der Compilierung
- von TINY-Programmen mit dem Parameter /t aufrufen und spart
- den Umweg über eine .EXE-Datei. Der Aufruf von TCC mit
-
- tcc -mt -lt hello
-
- compiliert HELLO.C und erzeugt dann die Datei HELLO.COM. (Das "-l" im
- Parameter "-lt" steht für "direkte Weitergabe des folgenden Befehls" -
- also "t" - an den Linker, vgl. Referenzhandbuch, Anhang).
-
- Hinweis: Die mathematische Bibliothek von Turbo C++ arbeitet wegen des
- Emulators in jedem Modell mit mehreren Segmenten. TINY-Programme, die
- Fließkommazahlen und -routinen benutzen, lassen sich deshalb auch mit
- TLINK nicht im .COM-Format speichern.
-
- G r a f i k
- ----------------------------------------------------------------------
- F. Mein Programm endet bei der ersten Grafikfunktion mit der Meldung
-
- BGI Error: graphics not initialized (use 'initgraph')
-
- - und das, obwohl initgraph() definitiv vorher aufgerufen wurde.
- A. initgraph() hat seine Funktion aus irgendeinem Grund (höchstwahr-
- scheinlich: Grafiktreiber nicht im momentan gesetzten Directory)
- nicht erfüllen können. Fügen Sie nach dem Aufruf von initgraph() eine
- Prüfung des Ergebnisses von graphresult() ein, und ermitteln Sie auf
- diese Weise den Fehlerstatus des Grafikpakets:
-
- #include <graphics.h>
- main()
- {
- int gerr; /* für das Ergebnis von graphresult() */
- int gdriver = DETECT, gmode;
-
- /* Initialisierung des Grafikpakets über die automatische
- Prüfung der Hardware. .BGI- und .CHR-Dateien werden im
- Directory C:\TURBOC gesucht:
- */
- initgraph(&gdriver, &gmode, "C:\\TURBOC"); /* "\\" ! */
-
- if ((gerr = graphresult()) != grOk)
- {
- printf("Fehler : %s\n", grapherrormsg(gerr));
- exit(1);
- }
-
- /* ..... */
- }
-
- M a t h e m a t i s c h e s
- ----------------------------------------------------------------------
- F. Die mathematischen Bibliotheksfunktionen liefern völlig unsinnige
- Ergebnisse.
- A. Vor der Verwendung von Funktionen wie cos() und tan() müssen
- Sie math.h mit #include in ihr Programm aufnehmen - ansonsten
- nimmt der Compiler an, daß diese Routinen den (Standard-)Ergebnistyp
- int haben und codiert entsprechende Zuweisungen. Da die meisten
- mathematischen Routinen Werte vom Typ double liefern, sind die
- Ergebnisse tatsächlich recht wunderlich. Beispiel:
-
- /* FUNKTIONIERT NICHT */ /* O.K. */
- #include <math.h>
- main() main()
- { {
- printf("%f", cos(0)); printf("%f", cos(0));
- } }
-
- F. Lassen sich Fließkomma-Fehler durch ein Programm abfangen?
- A. Die Funktion signal() ist unter anderem für die Behandlung von
- Fehlerbedingungen des Emulators und des 8087 bei direkten Befehlen
- vorgesehen; die Funktion matherr() für Bereichsüberschreitungen und
- unzulässige Argumente bei Routinen der Laufzeitbibliothek. Die ent-
- sprechenden Beschreibungen finden Sie im Referenzhandbuch.
-
- L i n k e r
- ----------------------------------------------------------------------
- F. Was hat die Meldung "Linker Error: Unable to open input file 'C0x.OBJ'"
- zu bedeuten?
- A. Siehe "Integrierte Entwicklungsumgebung" in dieser Datei.
-
- F. Welchen Grund hat die Meldung "Linker Error: Undefined symbol '_main'
- in module C0"?
- A. Jedes C-Programm muß genau eine Funktion mit dem Namen main
- definieren. Diese Funktion wird als "Hauptprogramm" durch den Start-
- code aufgerufen.
- (Daß der Linker dem Namen _main hier einen Unterstrich voranstellt,
- liegt an den allgemeinen Regeln zur Namensgebung in C - main ist
- ein global gültiges Symbol).
-
- F. Wieso beharrt der Linker darauf, daß die Funktionen des Grafikpakets
- "undefiniert" sind?
- A. Siehe "Integrierte Entwicklungsumgebung" und "Kommandozeilen-Version"
- in dieser Datei.
-
- F. Was bitte ist ein 'Fixup overflow'?
- A. Siehe Benutzerhandbuch, Anhang.
-
- F. Ich habe versucht, eigene Maschinenroutinen in mein C-Programm ein-
- zubinden - mit dem Ergebnis, daß diese Routinen für den Linker
- sämtlich "undefiniert" sind.
- A. Wahrscheinlich haben Sie einen der beiden folgenden Punkte übersehen:
-
- ■ C stellt jedem externen Bezeichner einen Unterstrich voran. Eine
- Routine, die im C-Quelltext als MyFunc deklariert ist, muß
- im Assembler-Quelltext als _MyFunc erscheinen.
- ■ Die meisten Assembler arbeiten ohne Unterscheidung zwischen Groß-
- und Kleinschreibung, solange sie nicht mit einem entsprechenden
- Zusatzparameter (für MASM und TASM: /MX) aufgerufen werden - und
- für den Linker von Turbo C++ sind _MYFUNC und _MyFunc zwei völlig
- verschiedene Dinge.
-
- D i v e r s e s
- ----------------------------------------------------------------------
- F. Wie läßt sich die Standardgröße des Stacks (4096 Bytes) ändern?
- A. Die Größe des Bereichs, den Turbo C++ für den Stack reserviert, wird
- zur Laufzeit des Programms durch den Wert der globalen Variablen
- _stklen festgelegt. Die folgende Deklaration legt beispielsweise
- fest, daß der Stack einen Umfang von 10000 Bytes haben soll:
-
- extern unsigned _stklen = 10000;
-
- ACHTUNG: Diese Anweisung darf sich nicht innerhalb einer Funktions-
- definition befinden.
-
- F. Mein Programm bricht mit der Meldung 'Stack Overflow!' ab. Was tun?
- A. Eine Möglichkeit besteht in einer Vergrößerung des Stacks (siehe
- oben); eine weitere in der Deklaration statischer anstelle
- dynamischer lokaler Variablen:
-
- main() main()
- { {
- char x[5000]; static char x[5000];
- /* belegt 5000 Bytes auf /* belegt 5000 Bytes im
- dem Stack */ Datensegment */
- } }
-
- ACHTUNG: "Speicherung im Datensegment" bedeutet hier auch: diese Variablen
- werden bei Rekursion nicht erneut kopiert.
-
- F. Mein Programm gibt nach seinem (anscheinend ordnungsgemäßen) Ende
- die beunruhigende Meldung 'Null pointer assignment' aus.
- A. Das bedeutet, daß Ihr Programm entweder eine Zuweisung über einen
- (vermutlich nicht initialisierten) Zeiger mit dem Wert NULL ausge-
- führt oder den Anfang seines Datensegments auf andere Art und Weise
- durcheinander gebracht hat.
-
- F. Wieso sind die mit TC.EXE erzeugten .EXE-Dateien größer als bei
- einer Compilierung durch die Kommandozeilen-Version?
- A. Die integrierte Entwicklungsumgebung bringt standardmäßig
- Informationen zur Fehlersuche mit dem integrierten Debugger in der
- .EXE-Datei unter (was auf die Ausführungsgeschwindigkeit übrigens
- keinen Einfluß hat). Diese zusätzlichen Informationen lassen sich
- mit Options/Debugger/Source debugging..None unterdrücken.
-
- F. Der Compiler meldet sich nach einem #include <dos.h> mit
- "Declaration syntax error".
- A. Sie haben O/C/Source/ANSI keywords only auf ON gesetzt. Dieser Schalter
- muß bei Verwendung von DOS.H auf OFF bleiben, weil diese Datei einige
- reservierte Wörter enthält, die nicht dem ANSI-Standard entsprechen.
-
- F. Ich habe ein Programm mit dynamischer Speicherverwaltung via malloc()
- und/oder calloc() geschrieben, das in den kleinen Datenmodellen
- (TINY, SMALL und MEDIUM) anstandslos funktioniert. Wenn ich aber
- eines der "großen" Modelle (COMPACT, LARGE oder HUGE) verwende,
- hängt sich das System auf.
- A. In diesen Modellen liefern malloc(), calloc() usw. FAR-Zeiger zurück -
- und deshalb müssen Sie die Datei ALLOC.H mit in Ihr Programm
- aufnehmen. Ansonsten erwartet der Compiler den (Standard-)Ergebnistyp
- int (= NEAR-Zeiger).
-
- F. Beim Einbinden eines selbstgeschriebenen Maschinenprogramms moniert
- der Linker die entsprechenden Symbole als "undefiniert".
- A. Siehe "Linker" in dieser Datei.
-
- F. Mit Far-Pointern kann ich nur 64 KByte adressieren. Was tun?
- A. Verwenden Sie Huge-Pointer.
-
- F. Kann ich mehr als 64 KByte globaler Variablen deklarieren?
- A. In allen Modellen außer HUGE dürfen globale und statische Variablen
- des gesamten Programms maximal 64 KByte belegen. Im Modell HUGE
- kann jedes Modul bis zu 64 KByte Daten definieren.
-
- F. Wie läßt sich ein Array deklarieren, das mehr als 64 KByte Gesamt-
- umfang hat?
- A. Arrays mit einem Umfang von mehr als 64 KByte müssen zur Laufzeit
- des Programms dynamisch belegt und über HUGE-Zeiger adressiert werden,
- sind aber in jedem der "großen Datenmodelle" möglich (d.h. nicht nur
- im Modell HUGE). Ein Array, das man normalerweise als
-
- char array[1024][128];
-
- deklarieren würde, wird hier folgendermaßen formuliert:
-
- #include <alloc.h>
-
- char (huge *array)[128]; /* ein HUGE-Zeiger auf ein Array mit
- 128 Zeigerelementen */
- main()
- {
- array = farcalloc(sizeof(*array), 1024);
- }
-
- Der Aufruf von farcalloc belegt für jedes der 128 Elemente des
- Arrays 1024 Bytes Platz auf dem Heap. Nach dieser Initialisierung
- läßt sich das Array in derselben Weise wie eine statische Variable
- adressieren. Eine Zuweisung wie
-
- i = array[30][56];
-
- setzt die Variable i auf den Wert des 31. Elements des 57. Arrays.
-
- F. Wie lassen sich mit Turbo C++ geschriebene Routinen in ein Turbo Pascal-
- Programm einbinden?
- A. Siehe CPASDEMO.PAS und CPASDEMO.C auf den Originaldisketten in der
- Datei EXAMPLES.ZIP. (Sie müssen diese Datei mit UNZIP auspacken).
-
- F. Wie lassen sich mit Turbo C++ geschriebene Routinen in ein Clipper-
- Programm einbauen?
- A. Falls sich dabei irgendwelche Probleme ergeben sollten, müssen wir
- auf die Hotline der Firma Nantucket verweisen.
-
- A l l g e m e i n e s z u C + +
- ----------------------------------------------------------------------
- F. Welche potentiellen Probleme können bei der Typ-Umwandlung eines
- Baisklassen-Zeigers in einen Zeiger einer abgeleiteten Klasse
- auftreten (damit die Elementfunktionen der abgeleiteten Klasse
- aufgerufen werden können)?
- A. Syntaktisch ist dies erlaubt. Es ist immer möglich, daß ein Basiszeiger
- auf eine Basisklasse zeigt. Wenn es sich um eine Umwandlung in einen
- abgeleiteten Typ handelt, existiert unter Umständen die Methode, die
- aufgerufen werden soll, in der Basisklasse NICHT. Sie würden daher
- die Adresse einer Funktion verwenden, die nicht existiert.
-
- F. Was ist der Unterschied zwischen den Schlüsselwörtern STRUCT und CLASS?
- A. Die Voreinstellung für Elemente einer STRUCT ist PUBLIC, für die Elemente
- einer CLASS dagegen PRIVATE. Sonst sind sie funktional äquivalent.
-
- F. Ich habe eine von einer Basisklasse abgeleitete Klasse deklariert, kann
- aber nicht über die abgeleitete Klasse auf die Basisklassen-Elemente
- zugreifen.
- A. Abgeleitete Klassen haben NIE Zugriff auf die privaten Elemente einer
- Basisklasse. Zugriff ist möglich, wenn die Elemente der Basisklasse als
- PUBLIC oder PROTECTED deklariert werden. Wenn sie PUBLIC sind, kann von
- jeder Stelle des Programms auf sie zugegriffen werden. Wenn sie PROTECTED
- sind, haben die Klassenelemente, Friends und jede abgeleitete Klasse
- Zugriff darauf.
-
- F. Wie kann ich die Paradox Engine mit C++ einsetzen?
- A. Weil alle Funktionen der Paradox Engine als C-Funktionen kompiliert
- sind, müssen Sie sicherstellen, daß die Namen dieser Funktionen nicht
- vom C++ Compiler behandelt werden. Die Engine-Funktionen müssen
- daher als extern "C" Funktionen definiert werden. Fügen Sie folgende
- Zeilen in die Datei pxengine.h an den bezeichneten Stellen ein:
-
- /* An Zeile # 268 einfügen */
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /* An Zeile # 732, vor dem letzten #endif, einfügen */
- #ifdef __cplusplus
- }
- #endif
-
- F. Ich habe eine Klasse, die von drei Basisklassen abgeleitet ist. Wie
- stelle ich sicher, daß ein bestimmter Basisklassen-Konstruktor vor
- allen anderen Konstruktoren aufgerufen wird?
- A. Wenn Sie die Basisklasse als virtuelle Basisklasse deklarieren, wird
- deren Konstruktor vor den anderen (nicht-virtuellen) Basisklassen-
- Konstruktoren aufgerufen. Normalerweise erfolgt der Aufruf der
- Konstruktoren von links nach rechts, nach der Reihenfolge der
- Deklarationen dieser Klasse.
-
- F. Sind die Ein-/Ausgabe-Funktionen der Standard-Library zusammen mit
- der C++ iostreams-Library verwendbar?
- A. Ja. Funktionen wie printf() und scanf() stehen weiterhin zur
- Verfügung, wenn Sie
-
- #include <stdio.h>
-
- angeben.
-
- F. Beim Debuggen mit dem Turbo Debugger ist mir aufgefallen, daß keine
- einzige meiner Inline-Funktionen expandiert worden ist. Sie werden
- alle wie Funktionsaufrufe behandelt. Was mache ich falsch?
- A. Immer dann, wenn Sie ein Programm kompilieren, in dem Debugger-Informa-
- tionen stehen, werden die Inline-Funktionen nicht expandiert. Um
- klarzustellen, daß die Funktionen korrekt expandiert werden, sollten
- Sie mit das Modul mit der Kommandozeilen-Version kompilieren. Benutzen
- Sie das Flag -S. Sehen Sie sich danach die generierte .ASM-Datei an.
-
- F. Wenn zwei Variablen mit dem gleichen Namen existieren, eine lokal,
- die andere global, wie kann ich dann vom Gültigkeitsbereich der
- lokalen Variablen aus auf die global definierte zugreifen?
- A. Benutzen Sie den Gültigkeitsbereichszugriffsoperator (::).
-
- int x = 10;
- for(int x=0; x < ::x; x++)
- {
- cout << "Schleife # " << x << "\n"; // wird 10x durchlaufen
- }
-
- F. Wird der Compiler die folgenden beiden Funktionen überladen oder
- einen Fehler melden? Warum?
- void test( int x, double y);
- int test( int a, double b);
- A. Der Compiler wird einen Deklarationsfehler melden, da weder Argument-
- namen noch Typen von Rückgabewerten bei der Bestimmung der Einzig-
- artigkeit einer überladenen Funktion eine Rolle spielen. Der Compiler
- sieht sich nur die Anzahl und die Typen der Argumente an.
-
- F. Wenn ich einen Character an eine Funktion übergebe, die nur Integer-
- Werte akzeptiert, wird der Compiler dann einen Fehler melden?
- A. Nein. Der Compiler benutzt die Integer-Repräsentation der Funktion
- anstatt das Zeichen selbst und konvertiert den Character-Wert in einen
- Integer-Wert.
-
- F. Ich habe versucht, mit Hilfe des Operators new Speicherplatz für ein
- Array mit Funktionszeigern zu reservieren, doch ich erhalte nur Syntax-
- fehler. Ich benutze folgende Notation: new int (*[10])();.
- Was ist falsch?
- A. Der Operator new ist ein unärer Operator, der auf das Schlüsselwort
- int wirkt und folgendes produziert: (new int) (*[10])();
- Schließen Sie also den Ausruck in Klammern ein, und Sie erhalten das
- gewünschte Resultat: new (int (*[10])());
-
- F. Was sind bitte Inline-Funktionen? Welche Vorteile haben sie, und wie
- sind sie deklariert?
- A. Eine Inline-Funktion ist eine Funktion, deren Inhalt (Text) vom
- Compiler eingefügt wird. Sie verhält sich ungefähr wie ein Makro.
- Der Vorteil ist, daß die Ausführungszeit kürzer wird, da kein
- Unterprogrammaufruf stattfindet.
- Inline-Funktionen werden folgendermaßen deklariert:
- inline void func(void) { cout << "Drucken der Inline-Funktion \n"; }
- Oder indem Funktionsdeklaration und Code in einer Klasse einbezogen werden
-
- class test
- {
- public:
- void func(void) { cout << "Inline-Funktion innerhalb einerKlasse.\n"}
- };
-
- F. Wenn ich in einer Klasse weder PUBLIC noch PRIVATE spezifiziere, was
- ist dann die Voreinstellung?
- A. Alle Elemente einer Klasse sind voreingestellt PRIVATE, wenn nichts
- anderes angegeben ist.
-
- F. Wozu dient der Modifizierer _seg?
- A. Wenn _seg benutzt wird, dann enthält der Zeiger eine Segmentadresse
- und keinen Offset. Ein Beispiel:
- "int _seg *x" enthält den Wert 0x40. Wenn Sie nun "*x" benutzen, befindet
- sich der Wert, auf den der Zeiger zeigt, im Segment 0x40, Offset 0.
- Wenn Sie einen Wert zum Zeiger addieren, wird dieser Wert mit der
- Größe des Zeigertyps multipliziert. Der neue Wert wird als Offset
- genutzt und mit dem Segmentment kombiniert. Ein Beispiel:
-
- int _seg *x;
- int value;
-
- x = (int _seg *)0x40;
- value = *(x + 20);
-
- Der Variablen value wird der Wert des Integers auf 0x40:0x28 zugewiesen
- (Erinnern Sie sich: 20 * sizeof(int) = 40 = 0x28).
-
- F. Kann ich statisch mehr als 64KByte für Daten in einem einzigen Modul
- reservieren?
- A. Ja. Far-Datenlemente werden nun unterstützt.
-
- ...
- char far array1[60000L];
- char far array2[60000L];
- ...
-
- Für Arrays größer als 64kByte:
-
- char huge array3[100000L];
-
- F. Wie kann man Hexadezimalwerte in Großbuchstaben über die IO-Stream-
- Libraries ausgeben?
- A. Benutzen Sie setf() wie im folgenden Beispiel:
-
- #include <iostream.h>
-
- int main(void)
- {
- cout << hex;
- cout << "\nKleinbuchstabe : " << 255;
- cout.setf(ios::upper-case);
- cout << "\nGroßbuchstabe : " << 255;
- return 0;
- }
-
- F. Um was handelt es sich bei dem Zeiger "this"?
- A. "this" ist eine lokale Variable im Rumpf einer nicht-statischen
- Elementfunktion. Es handelt sich um den zeiger auf das Klassenobjekt,
- mit dem diese aufgerufen werden. "this" kann nicht außerhalb einer
- Klassenelementfunktion verwendet werden.
-
- F. Warum akzeptiert eine binäre Elementfunktion nur ein einziges Argument?
- A. Das erste Element ist implizit definiert.
-
- F. Was bedeutet eine Deklaration als "Friend"?
- A. Friend bedeutet, daß Elemente, die nicht zu einer Klasse gehören,
- trotzdem Zugriff auf die nicht-PUBLIC Elemente dieser Klasse haben.
-
-