home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / tcpp / helpme!.doc next >
Text File  |  1990-06-09  |  33KB  |  730 lines

  1.              TURBO C++: ANTWORTEN AUF ALLGEMEINE FRAGEN
  2.  
  3.  
  4.  I n s t a l l a t i o n    u n d    S t a r t
  5.  ----------------------------------------------------------------------
  6.  F. Wie wird Turbo C++ auf meinem System installiert?
  7.  A. Legen Sie die Diskette 1 ("INSTALL") in das Laufwerk A:
  8.     Ihres Computers, setzen Sie dieses Laufwerk mit dem Befehl
  9.  
  10.       A: <RETURN>
  11.  
  12.     auf der DOS-Kommandoebene als Standard, und geben Sie dann den
  13.     Befehl
  14.  
  15.       INSTALL <RETURN>
  16.  
  17.     ein. INSTALL fragt nun als erstes, von welchem Disketten-
  18.     laufwerk die Dateien gelesen werden sollen. Tippen Sie
  19.  
  20.       A: <RETURN>
  21.  
  22.     Als nächstes erscheint nun das Menüsystem von INSTALL. Folgen Sie
  23.     den Anweisungen.
  24.  
  25.  F. Wie wird Turbo C++ nach der Installation gestartet?
  26.  A. Geben Sie auf der DOS-Kommandoebene
  27.  
  28.     TC <RETURN>
  29.  
  30.     ein, nachdem Sie Turbo C++ installiert haben.
  31.     Das Handbuch Einführung (Kapitel 2 des Benutzerhandbuchs) zeigt
  32.     schrittweise, wie es von diesem Punkt an weitergeht.
  33.  
  34.  F. Wo liegen die Unterschiede zwischen TC.EXE und TCC.EXE?
  35.  A. Das Turbo C++ Programmierpaket enthält zwei voneinander unabhängige
  36.     Compiler: die integrierte Entwicklungsumgebung (TC.EXE) und die
  37.     Kommandozeilen-Version TCC.EXE.
  38.       Bei ersterer handelt es sich um einen "Programmverbund" aus
  39.     Compiler, Editor, Debugger, kontextbezogener Hilfestellung usw., wobei
  40.     die einzelnen Funktionen über ein Menüsystem miteinander verbunden sind;
  41.     bei zweiterem um einen reinen Compiler, der durch die Eingabe
  42.     einer Kommandozeile (von der DOS-Kommandoebene aus) gestartet wird
  43.     und während der Bearbeitung eines C-Quelltextes keine weitere
  44.     Interaktion mit dem Benutzer ausführt.
  45.  
  46.  F. Was ist eine "Konfigurationsdatei"?
  47.  A. Über eine Konfigurationsdatei wird Turbo C++ mitgeteilt, welche
  48.     Einstellungen (Compiler-Schalter, Optionen usw.) als Standard ver-
  49.     wendet werden sollen und in welchen Directories sich Include-
  50.     Dateien bzw. Bibliotheken befinden.
  51.       TC.EXE - die integrierte Entwicklungsumgebung - sucht beim
  52.     Start nach einer Datei namens TCCONFIG.TC; TCC.EXE - die
  53.     Kommandozeilen-Version des Compilers - nach einer Datei namens
  54.     TURBOC.CFG.
  55.  
  56.  F. Wie werden Konfigurationsdateien erzeugt?
  57.  A. Von der integrierten Entwicklungsumgebung aus: durch die
  58.     Auswahl von Options/Save options. Turbo C++ speichert hier
  59.     sämtliche Daten, die von den durch Borland gesetzten
  60.     Vorgaben abweichen, in einer Datei, die standardmäßig
  61.     den Namen TCCONFIG.TC trägt.
  62.       Für die Kommandozeilen-Version: entweder durch
  63.     Konvertierung der Datei TCCONFIG.TC mit dem Programm
  64.     TCCONFIG.EXE (siehe Referenzhandbuch) oder durch die direkte
  65.     Eingabe mit einem ASCII-Editor (siehe Referenzhandbuch, Anhang).
  66.  
  67.  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
  68.  ----------------------------------------------------------------------
  69.  F. Anscheinend findet Turbo C++ meine mit #include <...> angegebenen
  70.     Dateien nicht. Wieso?
  71.  A. Der Compiler sucht Include-Dateien in den Directories, die über
  72.     Options/Directories/Include directories angegeben sind. Das Pro-
  73.     gramm INSTALL trägt hier das Directory ein, in das auch die
  74.     *.H-Dateien von den Originaldisketten kopiert wurden.
  75.       Wenn Sie eigene Include-Dateien erstellen und diese Dateien
  76.     in einem anderen Directory speichern, müssen Sie den Eintrag
  77.     in O/D/Include directories entsprechend erweitern. Mehrere
  78.     Einträge trennen Sie durch einen Strichpunkt ";".
  79.  
  80.  F. Ich erhalte die Meldung 'Linker error: Unable to open
  81.     input file 'C0x.OBJ''. Wieso?
  82.  A. Der Linker sucht den Startcode und die Laufzeitbibliotheken in den
  83.     Directories, die über Options/Directories/Library directories an-
  84.     gegeben sind. Das Programm INSTALL trägt hier das Directory ein,
  85.     in das auch die *.LIB und *.OBJ-Dateien von den Originaldisketten
  86.     kopiert wurden.
  87.  
  88.  F. Wie kriege ich den Compiler dazu, meine eigenen Bibliotheken anstelle
  89.     der Standardbibliotheken einzubinden? Wie sieht es mit mehreren
  90.     Quelltexten für ein Programm aus?
  91.  A. Siehe Benutzerhandbuch, Kapitel 3.
  92.  
  93.  F. Der Linker beharrt darauf, Funktionen wie initgraph() nicht zu
  94.     kennen. Wieso?
  95.  A. Setzen Sie den Schalter Options/Linker/Graphics Library auf ON oder
  96.     definieren Sie eine .PRJ-Datei, die graphics.lib explizit aufführt.
  97.  
  98.  F. Bei der Compilierung eines ganz gewöhnlichen Programms reagiert der
  99.     Compiler auf die Zeile #include <stdio.h> mit der Meldung
  100.     "Unable to open include file 'stdarg.h'".
  101.  A. Aller Wahrscheinlichkeit nach wurde die Maximalzahl von Dateien
  102.     überschritten, die DOS gleichzeitig offen halten kann. Fügen
  103.     Sie Ihrer Datei CONFIG.SYS die Zeile
  104.  
  105.         FILES=20
  106.  
  107.     hinzu - danach reserviert DOS genügend Platz, um bis zu 20
  108.     Dateien gleichzeitig bearbeiten zu können.
  109.       ACHTUNG: Die Datei CONFIG.SYS wird nur beim Start des Systems
  110.     ausgewertet - Sie müssen den Computer also neu starten, damit
  111.     Ihre Änderungen wirksam werden.
  112.  
  113.  F. Die Farben der Menüs von Turbo C++ passen absolut nicht zu meinem
  114.     Schreibtisch. Was tun?
  115.  A. Benutzen Sie TCINST.EXE zur Verwirklichung Ihrer eigenen Vorstellungen.
  116.  
  117.  F. Wie kann ich einen Quelltext am einfachsten drucken?
  118.  A. Aktivieren Sie den Editor von Turbo C++, laden Sie den Quelltext, und
  119.     geben Sie den Tastenbefehl Ctrl-K-P ein. Dieser Befehl sendet entweder
  120.     den momentan (mit Ctrl-K-B und Ctrl-K-K markierten) Block zum Drucker
  121.     - oder, falls überhaupt kein Block markiert ist, die gesamte Datei.
  122.  
  123.  F. Beim Aufruf von MAKE, Run oder bei der Aktivierung des Debuggers
  124.     übersetzt der Compiler manchmal verschiedene Teile meines Programms
  125.     von neuem - obwohl die einzelnen Module wirklich bereits auf dem
  126.     letzten Stand der Dinge sind.
  127.  A. MAKE orientiert sich ausschließlich an Datum und Uhrzeit
  128.     der einzelnen Dateien. Wenn Sie beispielsweise mit setfattr() expe-
  129.     rimentiert und einem Ihrer Quelltexte ein "Zukunftsdatum" verpaßt
  130.     haben, dann wird die entsprechende .OBJ-Datei für MAKE bis zum
  131.     tatsächlichen Erreichen dieses Zeitpunkts immer "älter" sein.
  132.     Diese und ähnliche Probleme lassen sich mit TOUCH lösen - einem
  133.     Programm, das sämtlichen angegebenen Dateien die momentane System-
  134.     zeit gibt.
  135.  
  136.  F. Warum funktionieren meine alten Turbo C++ Projekt-Dateien nicht mehr?
  137.  A. Projekt-Dateien enthalten nun wesentlich mehr Informationen und werden
  138.     deswegen nicht mehr im ASCII-Format gespeichert. Wenn Sie eine Projekt-
  139.     Datei erzeugen möchten, wählen Sie die Option Project aus dem Hauptmenü
  140.     und folgen den Menüs. Alte Projekt-Dateien können mit dem Hilfsprogramm
  141.     PRJCNVT.EXE (in UTIL.DOC beschrieben) in das neue Format konvertiert
  142.     werden.
  143.  
  144.  F. Warum wird meine Projekt-Datei automatisch geladen, wenn ich TC starte?
  145.     Ich möchte eigentlich mit anderen Dateien arbeiten.
  146.  A. Wenn sich nur eine Projekt-Datei im aktuellen Directory befindet,
  147.     lädt Turbo C++ diese Datei bei jedem Start. Wenn sich keine oder mehrere
  148.     Projekt-Dateien in diesem Directory befinden, wird keine automatisch
  149.     geladen.
  150.  
  151.  F. Die rechte Maustaste ist nicht aktiv. Kann ich das ändern?
  152.  A. Unter der Option Options/Environment/Mouse finden Sie ein Dialog-Fenster
  153.     für die rechte Maustaste. Sie können sie damit beliebig umdefinieren.
  154.  
  155.  F. Wie bringe ich Turbo C++ dazu, Expanded oder Extended Memory zu benutzen?
  156.  A. Benutzen Sie den Schalter /X für Extended und /E für Expanded Memory,
  157.     wenn Sie Turbo C++ starten.
  158.  
  159.  F. Beim Compilieren bekomme ich den Fehler "Error: C:\TC\INCLUDE\STDIO.H:
  160.     Overlays only supported in medium, large, and huge models
  161.     Was ist los?
  162.  A. Sie haben die Option Overlay Support ausgewählt, die nicht in den kleinen
  163.     Speichermodellen tiny, small und medium funktioniert. Deaktivieren Sie
  164.     die Option mit Options/Compiler/Code generation/Overlay Support
  165.  
  166.  F. Wenn ich nach dem Editieren einer Datei eine andere Datei laden will,
  167.     bleibt die erste Datei auf dem Bildschirm. Wie kann ich sie entfernen?
  168.  A. Schließen Sie mit Alt-F3 die aktuelle Datei. Mit F6 wechseln Sie
  169.     zwischen Dateien.
  170.  
  171.  F. Beim Suchen/Ersetzen muß ich jede Änderung bestätigen, auch wenn ich
  172.     Change All ausgewählt habe.
  173.  A. Deaktivieren Sie die Option "Prompt on replace" auf der linken Seite des
  174.     Dialog-Fensters.
  175.  
  176.  F. Wenn ich Pseudo-Register wie _AX verwende, erhalte ich beim Compilieren
  177.     Meldungen wie "Undefined symbol '_AX' in function...". Warum?
  178.  A. Pseudo-Register können nur im Turbo C++ und ANSI-Modus des Compilers
  179.     verwendet werden. Die Option finden Sie unter Options/Compiler/
  180.     Source menu.
  181.  
  182.  F. Wie kann ich, ohne eine Maus zu verwenden, Code zwischen Dateien
  183.     kopieren?
  184.  A. Markieren Sie den Block mit Ctrl-K-B (Anfangsmarke) und Ctrl-K-K
  185.     (Endemarke), und benutzen Sie dann die Copy- und Paste-Befehle des
  186.     Edit-Menüs. Sie können einen Block ebenso mit SHIFT-Pfeiltaste
  187.     markieren.
  188.  
  189.  K o m m a n d o z e i l e n - V e r s i o n
  190.  ----------------------------------------------------------------------
  191.  F. Anscheinend findet Turbo C++ meine mit #include <...> angegebenen
  192.     Dateien nicht. Wieso?
  193.  A. Der Compiler sucht Include-Dateien in den Directories, die über
  194.     den Parameter -I angegeben sind. Das Programm INSTALL erzeugt eine
  195.     Konfigurationsdatei (TURBOC.CFG), die von TCC.EXE automatisch gelesen
  196.     wird und in der das Directory eingetragen ist, in das auch die
  197.     *.H-Dateien von den Originaldisketten kopiert wurden.
  198.  
  199.  F. Ich erhalte die Meldung "Linker error: Unable to open
  200.     input file 'C0x.OBJ'". Wieso?
  201.  A. Der Linker sucht den Startcode und die Laufzeitbibliotheken in den
  202.     Directories, die über den Parameter -L der Konfigurationsdatei
  203.     TURBOC.CFG angegeben sind. Das Programm INSTALL trägt hier das
  204.     Directory ein, in das auch die *.LIB und *.OBJ-Dateien von den
  205.     Originaldisketten kopiert wurden.
  206.       Hinweis: Bei einem direkten Aufruf von TLINK müssen Sie den Such-
  207.     weg für Bibliotheken und Startcode explizit angeben - TLINK liest
  208.     die Konfigurationsdatei TURBOC.CFG nicht.
  209.  
  210.  F. Der Linker beharrt darauf, Funktionen wie initgraph() nicht zu
  211.     kennen. Wieso?
  212.  A. TCC sucht die Grafik-Bibliothek (graphics.lib) nur nach expliziter
  213.     Anweisung ab. Zur Compilierung von BGIDEMO ist beispielsweise die
  214.     folgende Kommandozeile notwendig:
  215.  
  216.         TCC BGIDEMO.C GRAPHICS.LIB <RETURN>
  217.  
  218.      Hinweis: Hier wurde vorausgesetzt, daß eine Konfigurationsdatei
  219.      TURBOC.CFG mit den Suchwegen für Bibliotheksdateien existiert.
  220.  
  221.  E i n -   u n d   A u s g a b e
  222.  ----------------------------------------------------------------------
  223.  F. Die Befehle  cprintf("Hello\n"); cprintf("world\n"); ergeben
  224.  
  225.            Hello
  226.                 world
  227.  
  228.     Woran liegt das?
  229.  A. cprintf() arbeitet in dieser Version von Turbo C++ so, wie
  230.     es eigentlich von Anfang an vorgesehen war - '\n' wird nicht
  231.     (wie bei printf) in eine CR/LF-Kombination "übersetzt", sondern
  232.     tatsächlich als einzelnes LF-Zeichen ausgegeben.
  233.       Wenn Sie den Cursor nicht nur eine Zeile tiefer, sondern auch
  234.     noch wieder in die Spalte 1 dieser Zeile setzen wollen, müssen Sie
  235.     das CR-Zeichen beim Aufruf von cprintf() direkt angeben: Die Befehls-
  236.     folge cprintf("Hello\n\r"); cprintf("world\n\r"); erzeugt das gewünschte
  237.     Ergebnis (wobei es keine Rolle spielt, ob '\r' vor '\n' oder danach
  238.     angegeben wird).
  239.  
  240.  F. Wie kann ich mit einem Programm Ausgaben auf dem Drucker erzeugen?
  241.  A. Ab der Version 1.5 von Turbo C ist eine FILE-Variable namens stdprn
  242.     in der Datei stdio.h definiert, die beim Start des Programms auto-
  243.     matisch geöffnet wird. Ein Beispiel dazu:
  244.  
  245.     #include <stdio.h>
  246.     main()
  247.     {
  248.       fprintf(stdprn, "Hello, world\n");
  249.     }
  250.  
  251.     Die meisten Drucker arbeiten übrigens mit einer zeilenweisen Pufferung -
  252.     tatsächlich gedruckt wird also erst nach dem abschließenden '\n'.
  253.  
  254.  F. Bei der Bearbeitung einer Binärdatei scheint sich Merkwürdiges zu tun,
  255.     wenn die Werte 0x0D und 0x0A gelesen oder geschrieben werden. Was tun?
  256.  A. Wahrscheinlich haben Sie die Datei ohne den Zusatz "b" geöffnet -
  257.     die Routinen zur Dateibearbeitung gehen dann von einer Textdatei aus
  258.     und übersetzen die Bytefolge 0x0D 0x0A als "CR/LF" in ein einzelnes LF beim
  259.     Lesen bzw. erweitern den Wert 0x0A als "LF" auf eine CR/LF-Folge beim
  260.     Schreiben.
  261.       Öffnen Sie die Datei explizit im Binärmodus, wie es das folgende
  262.     Beispiel zeigt:
  263.  
  264.       #include <stdio.h>
  265.       main()
  266.       {
  267.          FILE *binary_fp;
  268.          char buffer[100];
  269.  
  270.          binary_fp = fopen("MYFILE.BIN", "rb");
  271.  
  272.          fread(buffer, sizeof(char), 100, binary_fp);
  273.  
  274.                     :
  275.       }
  276.  
  277.  F. Wieso weigern sich printf() und puts(), farbige Zeichen zu erzeugen?
  278.  A. Weil diese beiden Funktionen mit Standardattributen arbeiten. Für
  279.     bunte Ausgaben und andere Spezialitäten des IBM PC sind die Routinen
  280.     cprintf() und cputs() vorgesehen:
  281.  
  282.       #include <conio.h>
  283.       main()
  284.       {
  285.          textcolor(BLUE);
  286.          cprintf("Ich bin blau.");
  287.       }
  288.  
  289.  F. Wie wird ein long-Wert mit printf ausgegeben?
  290.  A. Mit "%ld":
  291.  
  292.       long int l = 70000L;
  293.       printf("%ld", l);
  294.  
  295.  F. Wie wird ein Wert im Format long double (= Extended) ausgegeben?
  296.  A. Mit "%Lf":
  297.  
  298.       long double ldbl = 1E500;
  299.       printf("%Lf", ldbl);
  300.  
  301.  B e i s p i e l p r o g r a m m e
  302.  ----------------------------------------------------------------------
  303.  F. Wie wird BGIDEMO compiliert und gestartet?
  304.  A. 1. Die folgenden Dateien müssen sich im momentan gesetzten Directory
  305.        befinden:
  306.  
  307.          BGIDEMO.C
  308.          *.BGI       <- die Grafiktreiber
  309.          *.CHR       <- die Zeichensätze
  310.  
  311.     2. Starten Sie TC mit dem Befehl
  312.  
  313.          TC bgidemo <RETURN>
  314.  
  315.     3. Geben Sie den Tastenbefehl Ctrl-F9.
  316.  
  317.  F. Wie läßt sich mit Turbo C++ eine .COM-Datei erzeugen?
  318.  A. Zusammen mit den DOS-Versionen bis (inklusive) 3.2 wird ein Programm
  319.     namens EXE2BIN ("EXE to Binary") ausgeliefert, über das sich
  320.     .EXE-Programme des Speichermodells TINY ins .COM-Format umwandeln
  321.     lassen.
  322.       Wenn Sie EXE2BIN nicht Ihr eigen nennen: der zur Kommandozeilen-
  323.     Version von Turbo C++ gehörige Linker läßt sich bei der Compilierung
  324.     von TINY-Programmen mit dem Parameter /t aufrufen und spart
  325.     den Umweg über eine .EXE-Datei. Der Aufruf von TCC mit
  326.  
  327.      tcc -mt -lt hello
  328.  
  329.     compiliert HELLO.C und erzeugt dann die Datei HELLO.COM. (Das "-l" im
  330.     Parameter "-lt" steht für "direkte Weitergabe des folgenden Befehls" -
  331.     also "t" - an den Linker, vgl. Referenzhandbuch, Anhang).
  332.  
  333.     Hinweis: Die mathematische Bibliothek von Turbo C++ arbeitet wegen des
  334.     Emulators in jedem Modell mit mehreren Segmenten. TINY-Programme, die
  335.     Fließkommazahlen und -routinen benutzen, lassen sich deshalb auch mit
  336.     TLINK nicht im .COM-Format speichern.
  337.  
  338.  G r a f i k
  339.  ----------------------------------------------------------------------
  340.  F. Mein Programm endet bei der ersten Grafikfunktion mit der Meldung
  341.  
  342.        BGI Error: graphics not initialized (use 'initgraph')
  343.  
  344.     - und das, obwohl initgraph() definitiv vorher aufgerufen wurde.
  345.  A. initgraph() hat seine Funktion aus irgendeinem Grund (höchstwahr-
  346.     scheinlich: Grafiktreiber nicht im momentan gesetzten Directory)
  347.     nicht erfüllen können. Fügen Sie nach dem Aufruf von initgraph() eine
  348.     Prüfung des Ergebnisses von graphresult() ein, und ermitteln Sie auf
  349.     diese Weise den Fehlerstatus des Grafikpakets:
  350.  
  351.       #include <graphics.h>
  352.       main()
  353.       {
  354.         int gerr;   /* für das Ergebnis von graphresult() */
  355.         int gdriver = DETECT, gmode;
  356.  
  357.         /* Initialisierung des Grafikpakets über die automatische
  358.            Prüfung der Hardware. .BGI- und .CHR-Dateien werden im
  359.            Directory C:\TURBOC gesucht:
  360.         */
  361.         initgraph(&gdriver, &gmode, "C:\\TURBOC");  /* "\\" ! */
  362.  
  363.         if ((gerr = graphresult()) != grOk)
  364.         {
  365.             printf("Fehler : %s\n", grapherrormsg(gerr));
  366.             exit(1);
  367.         }
  368.  
  369.          /* ..... */
  370.       }
  371.  
  372.  M a t h e m a t i s c h e s
  373.  ----------------------------------------------------------------------
  374.  F. Die mathematischen Bibliotheksfunktionen liefern völlig unsinnige
  375.     Ergebnisse.
  376.  A. Vor der Verwendung von Funktionen wie cos() und tan() müssen
  377.     Sie math.h mit #include in ihr Programm aufnehmen - ansonsten
  378.     nimmt der Compiler an, daß diese Routinen den (Standard-)Ergebnistyp
  379.     int haben und codiert entsprechende Zuweisungen. Da die meisten
  380.     mathematischen Routinen Werte vom Typ double liefern, sind die
  381.     Ergebnisse tatsächlich recht wunderlich. Beispiel:
  382.  
  383.         /* FUNKTIONIERT NICHT */          /* O.K. */
  384.                                           #include <math.h>
  385.         main()                            main()
  386.         {                                 {
  387.           printf("%f", cos(0));             printf("%f", cos(0));
  388.         }                                 }
  389.  
  390.  F. Lassen sich Fließkomma-Fehler durch ein Programm abfangen?
  391.  A. Die Funktion signal() ist unter anderem für die Behandlung von
  392.     Fehlerbedingungen des Emulators und des 8087 bei direkten Befehlen
  393.     vorgesehen; die Funktion matherr() für Bereichsüberschreitungen und
  394.     unzulässige Argumente bei Routinen der Laufzeitbibliothek. Die ent-
  395.     sprechenden Beschreibungen finden Sie im Referenzhandbuch.
  396.  
  397.  L i n k e r
  398.  ----------------------------------------------------------------------
  399.  F. Was hat die Meldung "Linker Error: Unable to open input file 'C0x.OBJ'"
  400.     zu bedeuten?
  401.  A. Siehe "Integrierte Entwicklungsumgebung" in dieser Datei.
  402.  
  403.  F. Welchen Grund hat die Meldung "Linker Error: Undefined symbol '_main'
  404.     in module C0"?
  405.  A. Jedes C-Programm muß genau eine Funktion mit dem Namen main
  406.     definieren. Diese Funktion wird als "Hauptprogramm" durch den Start-
  407.     code aufgerufen.
  408.     (Daß der Linker dem Namen _main hier einen Unterstrich voranstellt,
  409.     liegt an den allgemeinen Regeln zur Namensgebung in C - main ist
  410.     ein global gültiges Symbol).
  411.  
  412.  F. Wieso beharrt der Linker darauf, daß die Funktionen des Grafikpakets
  413.     "undefiniert" sind?
  414.  A. Siehe "Integrierte Entwicklungsumgebung" und "Kommandozeilen-Version"
  415.     in dieser Datei.
  416.  
  417.  F. Was bitte ist ein 'Fixup overflow'?
  418.  A. Siehe Benutzerhandbuch, Anhang.
  419.  
  420.  F. Ich habe versucht, eigene Maschinenroutinen in mein C-Programm ein-
  421.     zubinden - mit dem Ergebnis, daß diese Routinen für den Linker
  422.     sämtlich "undefiniert" sind.
  423.  A. Wahrscheinlich haben Sie einen der beiden folgenden Punkte übersehen:
  424.  
  425.     ■ C stellt jedem externen Bezeichner einen Unterstrich voran. Eine
  426.       Routine, die im C-Quelltext als MyFunc deklariert ist, muß
  427.       im Assembler-Quelltext als _MyFunc erscheinen.
  428.     ■ Die meisten Assembler arbeiten ohne Unterscheidung zwischen Groß-
  429.       und Kleinschreibung, solange sie nicht mit einem entsprechenden
  430.       Zusatzparameter (für MASM und TASM: /MX) aufgerufen werden - und
  431.       für den Linker von Turbo C++ sind _MYFUNC und _MyFunc zwei völlig
  432.       verschiedene Dinge.
  433.  
  434.  D i v e r s e s
  435.  ----------------------------------------------------------------------
  436.  F. Wie läßt sich die Standardgröße des Stacks (4096 Bytes) ändern?
  437.  A. Die Größe des Bereichs, den Turbo C++ für den Stack reserviert, wird
  438.     zur Laufzeit des Programms durch den Wert der globalen Variablen
  439.     _stklen festgelegt. Die folgende Deklaration legt beispielsweise
  440.     fest, daß der Stack einen Umfang von 10000 Bytes haben soll:
  441.  
  442.       extern unsigned _stklen = 10000;
  443.  
  444.     ACHTUNG: Diese Anweisung darf sich nicht innerhalb einer Funktions-
  445.     definition befinden.
  446.  
  447.  F. Mein Programm bricht mit der Meldung 'Stack Overflow!' ab. Was tun?
  448.  A. Eine Möglichkeit besteht in einer Vergrößerung des Stacks (siehe
  449.     oben); eine weitere in der Deklaration statischer anstelle
  450.     dynamischer lokaler Variablen:
  451.  
  452.          main()                        main()
  453.          {                             {
  454.            char x[5000];                 static char x[5000];
  455.            /* belegt 5000 Bytes auf      /* belegt 5000 Bytes im
  456.               dem Stack */                  Datensegment */
  457.          }                             }
  458.  
  459.     ACHTUNG: "Speicherung im Datensegment" bedeutet hier auch: diese Variablen
  460.     werden bei Rekursion nicht erneut kopiert.
  461.  
  462.  F. Mein Programm gibt nach seinem (anscheinend ordnungsgemäßen) Ende
  463.     die beunruhigende Meldung 'Null pointer assignment' aus.
  464.  A. Das bedeutet, daß Ihr Programm entweder eine Zuweisung über einen
  465.     (vermutlich nicht initialisierten) Zeiger mit dem Wert NULL ausge-
  466.     führt oder den Anfang seines Datensegments auf andere Art und Weise
  467.     durcheinander gebracht hat.
  468.  
  469.  F. Wieso sind die mit TC.EXE erzeugten .EXE-Dateien größer als bei
  470.     einer Compilierung durch die Kommandozeilen-Version?
  471.  A. Die integrierte Entwicklungsumgebung bringt standardmäßig
  472.     Informationen zur Fehlersuche mit dem integrierten Debugger in der
  473.     .EXE-Datei unter (was auf die Ausführungsgeschwindigkeit übrigens
  474.     keinen Einfluß hat). Diese zusätzlichen Informationen lassen sich
  475.     mit Options/Debugger/Source debugging..None unterdrücken.
  476.  
  477.  F. Der Compiler meldet sich nach einem #include <dos.h> mit
  478.     "Declaration syntax error".
  479.  A. Sie haben O/C/Source/ANSI keywords only auf ON gesetzt. Dieser Schalter
  480.     muß bei Verwendung von DOS.H auf OFF bleiben, weil diese Datei einige
  481.     reservierte Wörter enthält, die nicht dem ANSI-Standard entsprechen.
  482.  
  483.  F. Ich habe ein Programm mit dynamischer Speicherverwaltung via malloc()
  484.     und/oder calloc() geschrieben, das in den kleinen Datenmodellen
  485.     (TINY, SMALL und MEDIUM) anstandslos funktioniert. Wenn ich aber
  486.     eines der "großen" Modelle (COMPACT, LARGE oder HUGE) verwende,
  487.     hängt sich das System auf.
  488.  A. In diesen Modellen liefern malloc(), calloc() usw. FAR-Zeiger zurück -
  489.     und deshalb müssen Sie die Datei ALLOC.H mit in Ihr Programm
  490.     aufnehmen. Ansonsten erwartet der Compiler den (Standard-)Ergebnistyp
  491.     int (= NEAR-Zeiger).
  492.  
  493.  F. Beim Einbinden eines selbstgeschriebenen Maschinenprogramms moniert
  494.     der Linker die entsprechenden Symbole als "undefiniert".
  495.  A. Siehe "Linker" in dieser Datei.
  496.  
  497.  F. Mit Far-Pointern kann ich nur 64 KByte adressieren. Was tun?
  498.  A. Verwenden Sie Huge-Pointer.
  499.  
  500.  F. Kann ich mehr als 64 KByte globaler Variablen deklarieren?
  501.  A. In allen Modellen außer HUGE dürfen globale und statische Variablen
  502.     des gesamten Programms maximal 64 KByte belegen. Im Modell HUGE
  503.     kann jedes Modul bis zu 64 KByte Daten definieren.
  504.  
  505.  F. Wie läßt sich ein Array deklarieren, das mehr als 64 KByte Gesamt-
  506.     umfang hat?
  507.  A. Arrays mit einem Umfang von mehr als 64 KByte müssen zur Laufzeit
  508.     des Programms dynamisch belegt und über HUGE-Zeiger adressiert werden,
  509.     sind aber in jedem der "großen Datenmodelle" möglich (d.h. nicht nur
  510.     im Modell HUGE). Ein Array, das man normalerweise als
  511.  
  512.        char array[1024][128];
  513.  
  514.     deklarieren würde, wird hier folgendermaßen formuliert:
  515.  
  516.       #include <alloc.h>
  517.  
  518.       char (huge *array)[128];  /* ein HUGE-Zeiger auf ein Array mit
  519.                                    128 Zeigerelementen */
  520.       main()
  521.        {
  522.           array = farcalloc(sizeof(*array), 1024);
  523.        }
  524.  
  525.     Der Aufruf von farcalloc belegt für jedes der 128 Elemente des
  526.     Arrays 1024 Bytes Platz auf dem Heap. Nach dieser Initialisierung
  527.     läßt sich das Array in derselben Weise wie eine statische Variable
  528.     adressieren. Eine Zuweisung wie
  529.  
  530.     i = array[30][56];
  531.  
  532.     setzt die Variable i auf den Wert des 31. Elements des 57. Arrays.
  533.  
  534.  F. Wie lassen sich mit Turbo C++ geschriebene Routinen in ein Turbo Pascal-
  535.     Programm einbinden?
  536.  A. Siehe CPASDEMO.PAS und CPASDEMO.C auf den Originaldisketten in der
  537.     Datei EXAMPLES.ZIP. (Sie müssen diese Datei mit UNZIP auspacken).
  538.  
  539.  F. Wie lassen sich mit Turbo C++ geschriebene Routinen in ein Clipper-
  540.     Programm einbauen?
  541.  A. Falls sich dabei irgendwelche Probleme ergeben sollten, müssen wir
  542.     auf die Hotline der Firma Nantucket verweisen.
  543.  
  544.  A l l g e m e i n e s   z u   C + +
  545.  ----------------------------------------------------------------------
  546.  F. Welche potentiellen Probleme können bei der Typ-Umwandlung eines
  547.     Baisklassen-Zeigers in einen Zeiger einer abgeleiteten Klasse
  548.     auftreten (damit die Elementfunktionen der abgeleiteten Klasse
  549.     aufgerufen werden können)?
  550.  A. Syntaktisch ist dies erlaubt. Es ist immer möglich, daß ein Basiszeiger
  551.     auf eine Basisklasse zeigt. Wenn es sich um eine Umwandlung in einen
  552.     abgeleiteten Typ handelt, existiert unter Umständen die Methode, die
  553.     aufgerufen werden soll, in der Basisklasse NICHT. Sie würden daher
  554.     die Adresse einer Funktion verwenden, die nicht existiert.
  555.  
  556.  F. Was ist der Unterschied zwischen den Schlüsselwörtern STRUCT und CLASS?
  557.  A. Die Voreinstellung für Elemente einer STRUCT ist PUBLIC, für die Elemente
  558.     einer CLASS dagegen PRIVATE. Sonst sind sie funktional äquivalent.
  559.  
  560.  F. Ich habe eine von einer Basisklasse abgeleitete Klasse deklariert, kann
  561.     aber nicht über die abgeleitete Klasse auf die Basisklassen-Elemente
  562.     zugreifen.
  563.  A. Abgeleitete Klassen haben NIE Zugriff auf die privaten Elemente einer
  564.     Basisklasse. Zugriff ist möglich, wenn die Elemente der Basisklasse als
  565.     PUBLIC oder PROTECTED deklariert werden. Wenn sie PUBLIC sind, kann von
  566.     jeder Stelle des Programms auf sie zugegriffen werden. Wenn sie PROTECTED
  567.     sind, haben die Klassenelemente, Friends und jede abgeleitete Klasse
  568.     Zugriff darauf.
  569.  
  570.  F. Wie kann ich die Paradox Engine mit C++ einsetzen?
  571.  A. Weil alle Funktionen der Paradox Engine als C-Funktionen kompiliert
  572.     sind, müssen Sie sicherstellen, daß die Namen dieser Funktionen nicht
  573.     vom C++ Compiler behandelt werden. Die Engine-Funktionen müssen
  574.     daher als extern "C" Funktionen definiert werden. Fügen Sie folgende
  575.     Zeilen in die Datei pxengine.h an den bezeichneten Stellen ein:
  576.  
  577.        /* An Zeile # 268 einfügen */
  578.        #ifdef __cplusplus
  579.        extern "C" {
  580.        #endif
  581.  
  582.        /* An Zeile # 732, vor dem letzten #endif, einfügen */
  583.        #ifdef __cplusplus
  584.        }
  585.        #endif
  586.  
  587.  F. Ich habe eine Klasse, die von drei Basisklassen abgeleitet ist. Wie
  588.     stelle ich sicher, daß ein bestimmter Basisklassen-Konstruktor vor
  589.     allen anderen Konstruktoren aufgerufen wird?
  590.  A. Wenn Sie die Basisklasse als virtuelle Basisklasse deklarieren, wird
  591.     deren Konstruktor vor den anderen (nicht-virtuellen) Basisklassen-
  592.     Konstruktoren aufgerufen. Normalerweise erfolgt der Aufruf der
  593.     Konstruktoren von links nach rechts, nach der Reihenfolge der
  594.     Deklarationen dieser Klasse.
  595.  
  596.  F. Sind die Ein-/Ausgabe-Funktionen der Standard-Library zusammen mit
  597.     der C++ iostreams-Library verwendbar?
  598.  A. Ja. Funktionen wie printf() und scanf() stehen weiterhin zur
  599.     Verfügung, wenn Sie
  600.  
  601.         #include <stdio.h>
  602.  
  603.     angeben.
  604.  
  605.  F. Beim Debuggen mit dem Turbo Debugger ist mir aufgefallen, daß keine
  606.     einzige meiner Inline-Funktionen expandiert worden ist. Sie werden
  607.     alle wie Funktionsaufrufe behandelt. Was mache ich falsch?
  608.  A. Immer dann, wenn Sie ein Programm kompilieren, in dem Debugger-Informa-
  609.     tionen stehen, werden die Inline-Funktionen nicht expandiert. Um
  610.     klarzustellen, daß die Funktionen korrekt expandiert werden, sollten
  611.     Sie mit das Modul mit der Kommandozeilen-Version kompilieren. Benutzen
  612.     Sie das Flag -S. Sehen Sie sich danach die generierte .ASM-Datei an.
  613.  
  614.  F. Wenn zwei Variablen mit dem gleichen Namen existieren, eine lokal,
  615.     die andere global, wie kann ich dann vom Gültigkeitsbereich der
  616.     lokalen Variablen aus auf die global definierte zugreifen?
  617.  A. Benutzen Sie den Gültigkeitsbereichszugriffsoperator (::).
  618.  
  619.        int x = 10;
  620.        for(int x=0; x < ::x; x++)
  621.        {
  622.            cout << "Schleife # " << x << "\n"; // wird 10x durchlaufen
  623.        }
  624.  
  625.  F. Wird der Compiler die folgenden beiden Funktionen überladen oder
  626.     einen Fehler melden? Warum?
  627.         void test( int x, double y);
  628.         int  test( int a, double b);
  629.  A. Der Compiler wird einen Deklarationsfehler melden, da weder Argument-
  630.     namen noch Typen von Rückgabewerten bei der Bestimmung der Einzig-
  631.     artigkeit einer überladenen Funktion eine Rolle spielen. Der Compiler
  632.     sieht sich nur die Anzahl und die Typen der Argumente an.
  633.  
  634.  F. Wenn ich einen Character an eine Funktion übergebe, die nur Integer-
  635.     Werte akzeptiert, wird der Compiler dann einen Fehler melden?
  636.  A. Nein. Der Compiler benutzt die Integer-Repräsentation der Funktion
  637.     anstatt das Zeichen selbst und konvertiert den Character-Wert in einen
  638.     Integer-Wert.
  639.  
  640.  F. Ich habe versucht, mit Hilfe des Operators new Speicherplatz für ein
  641.     Array mit Funktionszeigern zu reservieren, doch ich erhalte nur Syntax-
  642.     fehler. Ich benutze folgende Notation:  new int (*[10])();.
  643.     Was ist falsch?
  644.  A. Der Operator new ist ein unärer Operator, der auf das Schlüsselwort
  645.     int wirkt und folgendes produziert:  (new int) (*[10])();
  646.     Schließen Sie also den Ausruck in Klammern ein, und Sie erhalten das
  647.     gewünschte Resultat:  new (int (*[10])());
  648.  
  649.  F. Was sind bitte Inline-Funktionen? Welche Vorteile haben sie, und wie
  650.     sind sie deklariert?
  651.  A. Eine Inline-Funktion ist eine Funktion, deren Inhalt (Text) vom
  652.     Compiler eingefügt wird. Sie verhält sich ungefähr wie ein Makro.
  653.     Der Vorteil ist, daß die Ausführungszeit kürzer wird, da kein
  654.     Unterprogrammaufruf stattfindet.
  655.     Inline-Funktionen werden folgendermaßen deklariert:
  656.        inline void func(void) { cout << "Drucken der Inline-Funktion \n"; }
  657.     Oder indem Funktionsdeklaration und Code in einer Klasse einbezogen werden
  658.  
  659.        class test
  660.        {
  661.        public:
  662.        void func(void) { cout << "Inline-Funktion innerhalb einerKlasse.\n"}
  663.        };
  664.  
  665.  F. Wenn ich in einer Klasse weder PUBLIC noch PRIVATE spezifiziere, was
  666.     ist dann die Voreinstellung?
  667.  A. Alle Elemente einer Klasse sind voreingestellt PRIVATE, wenn nichts
  668.     anderes angegeben ist.
  669.  
  670.  F. Wozu dient der Modifizierer _seg?
  671.  A. Wenn _seg benutzt wird, dann enthält der Zeiger eine Segmentadresse
  672.     und keinen Offset. Ein Beispiel:
  673.     "int _seg *x" enthält den Wert 0x40. Wenn Sie nun "*x" benutzen, befindet
  674.     sich der Wert, auf den der Zeiger zeigt, im Segment 0x40, Offset 0.
  675.     Wenn Sie einen Wert zum Zeiger addieren, wird dieser Wert mit der
  676.     Größe des Zeigertyps multipliziert. Der neue Wert wird als Offset
  677.     genutzt und mit dem Segmentment kombiniert. Ein Beispiel:
  678.  
  679.        int _seg *x;
  680.        int value;
  681.  
  682.        x = (int _seg *)0x40;
  683.        value = *(x + 20);
  684.  
  685.     Der Variablen value wird der Wert des Integers auf 0x40:0x28 zugewiesen
  686.     (Erinnern Sie sich: 20 * sizeof(int) = 40 = 0x28).
  687.  
  688.  F. Kann ich statisch mehr als 64KByte für Daten in einem einzigen Modul
  689.     reservieren?
  690.  A. Ja. Far-Datenlemente werden nun unterstützt.
  691.  
  692.        ...
  693.        char far array1[60000L];
  694.        char far array2[60000L];
  695.        ...
  696.  
  697.     Für Arrays größer als 64kByte:
  698.  
  699.        char huge array3[100000L];
  700.  
  701.  F. Wie kann man Hexadezimalwerte in Großbuchstaben über die IO-Stream-
  702.     Libraries ausgeben?
  703.  A. Benutzen Sie setf() wie im folgenden Beispiel:
  704.  
  705.        #include <iostream.h>
  706.  
  707.        int main(void)
  708.        {
  709.           cout << hex;
  710.           cout << "\nKleinbuchstabe : " << 255;
  711.           cout.setf(ios::upper-case);
  712.           cout << "\nGroßbuchstabe : " << 255;
  713.           return 0;
  714.         }
  715.  
  716.  F. Um was handelt es sich bei dem Zeiger "this"?
  717.  A. "this" ist eine lokale Variable im Rumpf einer nicht-statischen
  718.     Elementfunktion. Es handelt sich um den zeiger auf das Klassenobjekt,
  719.     mit dem diese aufgerufen werden. "this" kann nicht außerhalb einer
  720.     Klassenelementfunktion verwendet werden.
  721.  
  722.  F. Warum akzeptiert eine binäre Elementfunktion nur ein einziges Argument?
  723.  A. Das erste Element ist implizit definiert.
  724.  
  725.  F. Was bedeutet eine Deklaration als "Friend"?
  726.  A. Friend bedeutet, daß Elemente, die nicht zu einer Klasse gehören,
  727.     trotzdem Zugriff auf die nicht-PUBLIC Elemente dieser Klasse haben.
  728.  
  729.  
  730.