C Programmierung

Gast #783036
Lesenswert?

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.
Gast #783061
Lesenswert?

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.
#783067
Lesenswert?

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.
#783072
Lesenswert?

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.
#783074
Lesenswert?

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.
Gast #783076
Lesenswert?

>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.
Persönliche Seite #783146
Lesenswert?

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)
Moderator Persönliche Seite #783162
Lesenswert?

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.
#783180
Lesenswert?

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.
Moderator Persönliche Seite #783186
Lesenswert?

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.)
Moderator Persönliche Seite #783244
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren