Es geht darum die Werte aus einer externen Datei (data.dat) in ein Array
einzulesen. Die Daten liegen Kommagetrennt vor.
Bin auf folgende Codezeile gestoßen:
int dm data_tx[100] = { #include "data.dat" };
Geht das damit tatsächlich? Ich habe früher immer eine richtige
Dateiarbeit mit Schleifen aufgesetzt...
Kann ich das damit also machen? Sind euch irgendwelche Vor-/Nachteile
bekannt???
DANKE.
Du missbrauchst hier den C-Präprozessor um den Inhalt des angegebenen
Files an die Stelle des Includes zu schreiben. Solange das File so
gebaut ist, dass es in den Kontext der Array Initialisierung passt wird
das wohl gehen.
Wo hastn das her?
Soweit ich das weiss, geht das mit einem Standardkonformen kompiler
bestimmt nicht.. Das '#'-Zeichen, das ein Prefix für eine
Precompiler-Anweisung verwendet wird, muss immer am Zeilenanfang stehen.
Hinzukommt, daß eine include-Datei nicht an der Stelle in den Quellcode
eingefügt wird, sondern sie wird in der Regel für sich alleine geparst.
Niels Hüsken wrote:
> Hinzukommt, daß eine include-Datei nicht an der Stelle in den Quellcode> eingefügt wird, sondern sie wird in der Regel für sich alleine geparst.
Nö. Gerade eine #includierte Datei wird natürlich nicht separat
geparst. Andernfalls könnte man keine Deklarationen in Headerdateien
machen...
Ich denke Du verwechselst da was: Dateien, die nicht mit #include
eingebunden werden, werden separat bearbeitet, was der Grund für die
Verwendung von Header-Dateien mit Prototypen- und "extern"-Deklarationen
ist (die dann wiederum mit #include eingebunden werden, damit der
Compiler beim Parsen der betreffenden Datei die Variablen und Funktionen
kennt).
Eine mit #include eingebundene Datei wird (vom Präprozessor) 1:1 an der
Stelle der #include-Anweisung eingefügt.
Die include-Datei wird seperat nur vom Präprozessor geparsed, aus Sicht
des C-Compilers gibt es nur eine einzige Datei, in die schon alle
includes eingefügt sind.
Von daher geht das "richtige" Beispiel von Jörg Wunsch und ist nicht
unüblich, wenn Daten in ein Programm hineinkompiliert werden sollen /
müssen.
>Geht das damit tatsächlich? Ich habe früher immer eine richtige>Dateiarbeit mit Schleifen aufgesetzt...
der Unterschied ist hoffentlich klar: so wird der Dateiinhalt zur
Laufzeit gelesen, beim #include wird die Variable zur Kompilierzeit
festgelegt. Für Daten die sich nicht mehr ändern ist includieren schon
praktisch, z.B. für Zeichenfonts für Displays die man mit dann mit einem
externen Tool erzeugen kann.
Sven Scholz wrote:
> Es geht darum die Werte aus einer externen Datei (data.dat) in ein Array> einzulesen. Die Daten liegen Kommagetrennt vor.
Soll das Einlesen denn zum Zeitpunkt des Kompilierens oder später zur
Laufzeit geschehen?
Bernhard M. wrote:
> Die include-Datei wird seperat nur vom Präprozessor geparsed, aus Sicht> des C-Compilers gibt es nur eine einzige Datei, in die schon alle> includes eingefügt sind.
Die Datei wird soweit ich weiß nicht einzeln geparsed. Bei einem
#include wird sämtlicher Text der inkludierten Datei 'reingeholt und
anschließend wird weitergeparsed (nicht nach den inkludierten Daten,
sondern am Anfang der inkludierten Daten)
Simon K. wrote:
>> Die include-Datei wird seperat nur vom Präprozessor geparsed, ...> Die Datei wird soweit ich weiß nicht einzeln geparsed.
Nein, obige Aussage ist schon korrekt: die include-Datei wird vom
Präprozessor separat geparsed. Der Präprozessor arbeitet dabei
(anders als der C-Compiler selbst) simpel zeilenweise alles durch.
Sein Parser ist aber sehr einfach, da er nur die Präprozessoranweisungen
selbst (mit # beginnend) und gültige C-Namen erkennen muss. Letztere
sind potenzielle Kandidaten für eine mögliche Makro-Ersetzung, daher
muss der Präprozessor sie bereits parsen.
Das ist nichtmal auf C Identifikatoren festgelegt, der GNU Assembler
benutzt auch den (C-)Präprozessor.
Die Sache mit dem #include ist aber gerade eine der schönen Seiten von
C/C++. Man muss nicht wissen wierum der Compiler irgendwelche Dateien
liest oder was er als erstes parst, das gibt man als Programmierer
einfach im Code vor und genauso und nicht anders wird es gemacht -
eingebundene Dateien erscheinen da wo's #include steht.
I_ H. wrote:
> Das ist nichtmal auf C Identifikatoren festgelegt, der GNU Assembler> benutzt auch den (C-)Präprozessor.
Nein. ;-)
Wenn, dann macht das der Compiler, indem du ihm eine .S-Datei
übergibst. Er ruft dann den Präprozessor auf und mit dem Ergebnis
den Assembler.
Trotzdem bleibt die Ersetzung der Makros auf C-Bezeichner beschränkt.
Wenn also der Assembler eine andere Syntax für Bezeichner benutzen
würde (beispielsweise Namen gestatten, die einen Punkt beinhalten),
dann könnte man diese nicht durch Makros ersetzen lassen.
Da der Präprozessor aber eben den Rest nicht parsed, kann das ein
ansonsten beliebiger Text sein. (C-Kommentare ersetzt er übrigens
noch durch Leerzeichen.)
GAS benutzt es soweit ich weis auch. Klar, eigentlich sind C Identifier
gemeint, aber es wird halt auch an anderer Stelle benutzt. Der Rest ist
Wortklauberei.
I_ H. wrote:
> GAS benutzt es soweit ich weis auch.
Nein, macht er eben nicht. Nur, wenn du den Assembler über den
Compiler rufst.
1
% cat foo.S
2
#define FOO 42
3
mov %eax, FOO
4
% as -o foo.o foo.S
5
% nm foo.o
6
U FOO
7
% objdump -d foo.o
8
9
foo.o: file format elf32-i386
10
11
Disassembly of section .text:
12
13
00000000 <.text>:
14
0: a3 00 00 00 00 mov %eax,0x0
15
% cc -c -o foo.o foo.S
16
% nm foo.o
17
% objdump -d foo.o
18
19
foo.o: file format elf32-i386
20
21
Disassembly of section .text:
22
23
00000000 <.text>:
24
0: a3 2a 00 00 00 mov %eax,0x2a
Gut erkennbar, dass die 42 nur im zweiten Fall ersetzt worden ist, im
ersten Fall ist das ganze #define ein Kommentar für den Assembler, und
FOO wurde nicht ersetzt sondern (stillschweigend) als "external
undefined" in die Symboltabelle aufgenommen. Der Linker würde sich
dann später darüber erbrechen, dass er keine Definition für das
globale Symbol FOO finden kann.