www.mikrocontroller.net

Forum: Compiler & IDEs anfaengerfrage


Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi.
Ich habe ein paar kleine Routinen in C für meinen uC geschrieben. Es
funktioniert soweit auch alles, aber meine main.c wird langsam etwas zu
lang. Ich würde gerne ein paar Funktionen in externe c.files auslagern.
Gibt es eine Möglichkeit, dass die externen c.files die globalen
Variablen aus dem main kennnen, oder muss man dass immer alles einzeln
übergeben?

Autor: Sven Bohner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klaro,

in main.c:

int globaleVariable1;


in nem andern quellfile:

extern int globaleVariable1; //variablenname muss genau dem
      //im main.c ensprechen

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besser ist es, für so etwas eine Headerdatei zu verwenden und diese in
die entsprechenden Module einzubinden.

Auch sollten, der Struktur halber, die globalen Variablen nicht im
Hauptmodul, sondern in einem eigenen Modul definiert werden.

Beispiel:

--- global.h
// Deklaration
extern int globaleVariable1;
extern int globaleVariable2;


--- global.c

#include "global.h"

// Definition
int globaleVariable1;
int globaleVariable2;

--- main.c

#include "global.h"

... etc.
  globaleVariable1 = 0;


--- krempel.c

#include "global.h"

... etc.
  globaleVariable1 = 0;



Um Tippfehler auszuschließen, kann man auch so vorgehen:

--- global.h

#ifdef IMPLEMENTIERUNG
// Definition
#define bla
#else
// Deklaration
#define bla extern
#endif

bla globaleVariable1;
bla globaleVariable2:

--- global.c

#define IMPLEMENTIERUNG
#include "global.h"

// und nichts weiter

--- main.c

#include "global.h" (wie gehabt)

... etc.
  globaleVariable1 = 0;



So müssen globale Variablen ausschließlich einmal in einer Headerdatei
aufgelistet werden und deren Definition und Deklaration erfolgt durch
die gleiche Headerdatei.
Das Makro IMPLEMENTIERUNG darf nur exakt einmal beim Einbinden der
Headerdatei definiert sein (das sorgt dafür, daß dann das Schlüsselwort
"extern" entfällt).

Es gibt C-Compiler, die einem das Leben einfacher machen, in dem sie
(genauer: deren Linker) Symbole gleichen Namens zusammenfasst (da
genügt es, in jedem Modul die globalen Variablen mit gleichem Namen zu
definieren), aber das ist nicht portierbar und dürfte auch
(tipp)-fehleranfällig sein.

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah ha! Cool. Danke

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rufus
In jedem Fall drucke ich mir das mal für spätere Verwednung auf aber im
Moment komme ich wohl mit Svens Version besser zurecht. Trotzdem Danke

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das Makro IMPLEMENTIERUNG darf nur exakt einmal beim
> Einbinden der Headerdatei definiert sein

a) <mode="haarspalter">das ist kein Makro, sondern ein
Präprozessorsymbol (ein Makro hat Parameter) </mode>
b) nach dem Standard dürfen globale Symbole niemals mit einem
Unterstrich beginnen, wenn du nicht gerade an der libc programmierst.
Darunter fallen insbesondere auch Präprozessorsymbole, auch wenn das
gerne falsch gemacht wird. Richtig wäre also "#define
IMPLEMENTIERUNG" (Unterstriche am Ende des Bezeichners sind aber
erlaubt). Normalerweise sorgt die GROSS-Schreibung schon dafür, dass
eine keine Namenskollisionen gibt.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chris: Schöne Haarspalterei.

Was machst Du jetzt mit den gespaltenen Haaren? Zusammenknoten?

Zum Punkt b) Sieh Dir mal die ganzen #defines in etlichen Sourcen (MFC,
wxWidgets, was weiß ich wo) an - da wird ein führender Unterstrich
äußerst gerne verwendet. Auch ist die Abfolge

  #ifndef _INC_STDIO
  #define _INC_STDIO

  ... viele Zeilen

  #endif  /* _INC_STDIO */

äußerst beliebt, um Mehrfacheinbindungen auszuschließen.
(Zitat aus stdio.h, enthalten im Lieferumfang von MSVC6)

Das scheint auch nicht MS-spezifisch zu sein:

  #ifndef __stdio_h
  #define __stdio_h

  ... viele Zeilen

  #endif

(hier: stdio.h von Rowley Crossworks for ARM)

Welchen Standard meinst Du mit "dem Standard"?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
stdio.h ist auch Teil der ,Implementierung', die dürfen das.

Wenn wxWidgets das auch macht, riskieren sie u. U. eine Kollission mit
Compiler und/oder Bibliothek.

Als Anwender gilt uneingerschränkt: definiere nie selbst irgendwelche
Namen, die mit einem Unterstrich anfangen.  (Ob du derartige Namen,
die die Implementierung benutzt, auch benutzen darfst, d.h. ob sie
ein exportiertes Interface darstellen, erzählt die die jeweilige
Doku.)

Header `idempotency' kann man für seine Applikations-Header auch ohne
den Unterstrich locker erreichen:

#ifdef MYAPP_H
#define MYAPP_H
...
#endif /* MYAPP_H */

Ob das Zeug woanders gerne verwendet wird oder nicht, spielt keine
Geige, es bleibt falsch.  Besonders deutsche Autofahrer fahren auch
gern mal schneller, als die Polizei erlaubt -- und riskieren dafür
genauso eine entsprechende Quittung wie C-Programmierer, die sich
nicht an die Regeln halten.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Joerg:
Ich wollte hier keinerlei Diskussion lostreten.

Daher mein Beispiel von neulich in "korrigierter" Fassung:

  #ifdef IMPLEMENTIERUNG
  // Definition
  #define VIELLEICHT_EXTERN
  #else
  // Deklaration
  #define VIELLEICHT_EXTERN extern
  #endif

  VIELLEICHT_EXTERN globaleVariable1;
  VIELLEICHT_EXTERN globaleVariable2:

  --- global.c

  #define IMPLEMENTIERUNG
  #include "global.h"

  // und nichts weiter

  --- main.c

  #include "global.h" (wie gehabt)

  ... etc.
  globaleVariable1 = 0;


Zufrieden?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja. :-)

Rufus, das Problem ist, dass du aufgrund deiner guten Beiträge
natürlich ringsum ganz schnell ,,Guru-Status'' erhälst und damit für
andere zum Vorbild wirst...  Da sollte man sich dann einfach Mühe
geben, auch auf derartige Kleinigkeiten zu achten.

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich das richtig interpretiere gibt es also Funtionen, die über das
"Standart - C" hinausgehen, (sagen wir mal um die Arbeit zu
vereinfachen) die dann alle mit einem oder 2 Unterstrichen anfangen,
damit sie nicht genauso heißen, wie zB eine vom Programmierer
geschriebene Funktion  Makro  Variable  ... was auch immer??

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ungefähr.

Der Standard schreibt genau vor, welche Funktionen und Makros
definiert werden, wenn man eine bestimmte Header-Datei
(z. B. <stdio.h>) hereinzieht.  Es ist vorgeschrieben, was danach
deklariert bzw. definiert sein muss, und was als mögliche Erweiterung
sein darf.  (Z. B. reserviert <string.h> alle Funktionsnamen, die mit
"str" beginnen.)

Wenn eine Implementierung jetzt für irgendwas zusätzliche internen
Namen benötigt, muss sie diese zur Vermeidung von Kollisionen aus dem
Namensraum belegen, der für die Implementierung vorbehalten ist.
Benötigt beispielsweise ein <stdio.h> zur Implementierung von "FILE
*"
eine struct, deren Name im Headerfile für die Applikation sichtbar
wird, dann darf sie nicht "struct file" nehmen (weil das mit der
Applikation kollidieren kann), sondern muss "struct _file" nehmen.

Der Unterschied zwischen einem und zwei Unterstrichen ist aus
Benutzersicht marginal und kann hier vernachlässigt werden.

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eine fehlt noch ...
Ich habe ein "volatile static char", dass mir sozusagen als
Escape-Taste dient. Die bekomme ich einfach nicht hin bei der
Auslagerung. Gibt es da noch was zu beachten?

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"static" bedeutet, daß das Symbol nicht auf Linkerebene sichtbar ist.
Somit kann Code aus einem Modul nicht auf eine in einem anderen Modul
als static definierte Variable zugreifen, ebensowenig, wie Code aus
einem Modul nicht auf als static deklarierten Code in einem anderen
Modul zugreifen kann.

Dir dürfte damit geholfen sein, wenn Du das "static" entfernst.

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na das werde ich doch gleich mal ausprobieren. Danke

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klappt super. Ich muss wohl noch ein bisschen an meiner
Programmstrukturierung arbeiten.

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.