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.
Sven Scholz wrote: > int dm data_tx[100] = { #include "data.dat" }; > > Geht das damit tatsächlich? Laut C-Standard so nicht, aber so:
1 | int dm data_tx[100] = { |
2 | #include "data.dat" |
3 | };
|
Das # muss das erste (nichtleere) Zeichen in der Zeile sein.
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.
Jörg Wunsch wrote:
> Laut C-Standard so nicht, aber so: [...]
gut, dann bin ich falsch informiert ;)
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.