www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C Programmierung


Autor: Sven Scholz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: schnudl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven Scholz wrote:

> int dm data_tx[100] = { #include "data.dat" };
>
> Geht das damit tatsächlich?

Laut C-Standard so nicht, aber so:
int dm data_tx[100] = {
#include "data.dat"
};

Das # muss das erste (nichtleere) Zeichen in der Zeile sein.

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:

> Laut C-Standard so nicht, aber so: [...]


gut, dann bin ich falsch informiert ;)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
% cat foo.S
#define FOO 42
mov %eax, FOO
% as -o foo.o foo.S
% nm foo.o
         U FOO
% objdump -d foo.o

foo.o:     file format elf32-i386

Disassembly of section .text:

00000000 <.text>:
   0:   a3 00 00 00 00          mov    %eax,0x0
% cc -c -o foo.o foo.S
% nm foo.o
% objdump -d foo.o

foo.o:     file format elf32-i386

Disassembly of section .text:

00000000 <.text>:
   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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.