mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik #define Variablen


Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich Variablen so deklariere:
#define G 9.81
Was für einen Datentyp wird den da erzeugt? double, float,..?

Autor: Helmut -dc3yc (dc3yc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven,

so definierst du überhaupt keine Variable. Du sagst nur dem Precompiler, 
dass er überall, wo G steht, das durch 9.81 ersetzen soll.

Servus,
Helmut.

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja und wenn ich dann beispielweise eine operation ausführe:

10*G;

dann muss das doch irgeindein datentyp sein dass man damit rechnen kann?

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast den Hintergrund noch nicht verstanden. #define ist eine 
Anweisung für den Precompiler, das Programm VOR (Pre) dem Compiler. Das 
ist ein Programm, das einen Text (G) durch einen anderen (9.81) ersetzt. 
Der Compiler, nur der kennt Datentypen, bekommt das G nie zu sehen. In 
deinem Beispiel stünde da: 10*9.81 .

Wenn du Constanten mit Typ definieren willst, musst du das mit "const 
double g = 9.81;" machen. Das wird vom Compiler verarbeitet.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlev T. wrote:

> Wenn du Constanten mit Typ definieren willst, musst du das mit "const
> double g = 9.81;" machen.

Damit wird allerdings eine Variable angelegt, d.h. SRAM verbraucht.
Außerdem dauert das Adressieren einer Variablen länger als das Laden 
einer Konstanten.

Das ist in der Regel bei Konstanten auch nicht nötig.

Besser daher:
#define G ((double)9.81)

Aber einbuchstabige defines und Variablen sind generell schlecht (zu 
finden oder umzubenennen). Man sollte mindestens 3 Zeichen nehmen.


Peter

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aus 10*G wird nach dem PreProzessor 10*9.81
Der Compiler wird daraus eine FLOAT Berechung machen, also die 
entsprechenden Libaries einbinden, falls er sie hat, oder eine 
Fehlermeldung ausgeben.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe auch eine Frage am Rand.
Wenn ich eine funktion xy() habe und darin ein Variable vom Typ char 
deklariere, wahn und wo lohnt sich diese Variable zu initialisieren, 
wenn man sowieso davon ausgeht, dass dieser Variable ein neuer Wert 
erteilt wird?

Z.B.

u8 xy(u8 a)
{
  u8 b;
  b = a;
  return b;
}

oder

u8 xy(u8 a)
{
  u8 b=0x00;
  b = a;
  return b;
}

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ralph
Der Compiler wird, wenn er einigermassen was taugt, deshalb keine Libs 
einbinden, denn er wird den Wert schon beim compilieren berechnen!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast wrote:
> Wenn ich eine funktion xy() habe und darin ein Variable vom Typ char
> deklariere, wahn und wo lohnt sich diese Variable zu initialisieren,
> wenn man sowieso davon ausgeht, dass dieser Variable ein neuer Wert
> erteilt wird?
>
> Z.B.
>
> u8 xy(u8 a)
> {
>   u8 b;
>   b = a;
>   return b;
> }
>
> oder
>
> u8 xy(u8 a)
> {
>   u8 b=0x00;
>   b = a;
>   return b;
> }

Wenn du Variable dann sowieso einen neuen Wert bekommt, warum
initialisierst du sie dann nicht einfach mit genau diesem 'neuen'
Wert

u8 xy(u8 a)
{
   u8 b = a;
   return b;
}

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Frank

Ok einverstanden für 10*9.81 setzt der Compiler direkt 98.1 ein

Aber dieser Wert (98.1) wird ja irgendwo verwendet werden. Bei der 
nächsten Verwendung kommen die Float Libs.. zum Zuge.


Variablen initialisierung:

Sauber und Sicher ist es, wenn du jede Variable bei oder nach der 
Deklaration sofort Initialisiert.

Wenn du sicherstellen kannst, das ein definierter Schreibzugriff vor dem 
1.Lesezugriff auf die Variable durchgeführt wird, dann kannst du die 
Initialierung weglassen.
Aber Achtung, du spart damit eine Zuweisung,also geringfügig Code, aber 
nimmst damit ein großes Risiko in Kauf das du bei einem Lesezugriff 
einen ungültigen Wert in einer Variable hast.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:
>> Wenn du Constanten mit Typ definieren willst, musst du das mit "const
>> double g = 9.81;" machen.
>
> Damit wird allerdings eine Variable angelegt, d.h. SRAM verbraucht.

Das sollte eigentlich nicht passieren, wenn der Compiler was taugt. Eine 
solche Konstruktion nennt man "benannte Konstante". Da "weiß" der 
Compiler, dass sie unveränderlich ist und daher keinen Speicherplatz 
braucht.

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph wrote:
> @Frank
>
> Ok einverstanden für 10*9.81 setzt der Compiler direkt 98.1 ein
>
> Aber dieser Wert (98.1) wird ja irgendwo verwendet werden. Bei der
> nächsten Verwendung kommen die Float Libs.. zum Zuge.

Wenn die Zuweisung an eine Integervariable erfolgt dann werden da gar 
keine Libs dazugebunden da der Compiler bereits zur Compilezeit die 
Umwandlung vornehmen kann.

Detlev T. wrote:
> Peter Dannegger wrote:
>>> Wenn du Constanten mit Typ definieren willst, musst du das mit "const
>>> double g = 9.81;" machen.
>>
>> Damit wird allerdings eine Variable angelegt, d.h. SRAM verbraucht.
>
> Das sollte eigentlich nicht passieren, wenn der Compiler was taugt. Eine
> solche Konstruktion nennt man "benannte Konstante". Da "weiß" der
> Compiler, dass sie unveränderlich ist und daher keinen Speicherplatz
> braucht.

Bei einem "const double" weiß er das nicht da das Ding noch in einem 
anderen Modul (dort sogar als einfaches "double") verwendet werden kann. 
Somit muss der Compiler Speicherplatz reservieren. Der Linker der das 
dann auflösen könnte weiß aber nichts mehr über evtl. vorhandene 
Modifizierer. Der kennt nur noch Namen und Größen. Was man allerdings 
machen kann ist das Teil "static const double" zu machen. Dann kann es 
der Compiler wirklich wegoptimieren da die Variable in anderen Modulen 
nicht sichtbar ist.

Matthias

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Matthias
Aus meiner Sicht gibt so ein Modifier zusätzliche Informationen an den 
Compiler für zwei Aufgaben:
1) Der Compiler kann den Code besser optimieren (auch z.B. const 
Variablen ins ROM)
2) Er kann Inkonsistenten detektieren und den Programmierer warnen. 
Beispiel:
#include <stdio.h>

const int x_const = 1;
      int x_var   = 2;

void foofunc(int * x)
{
 *x = 4;
}

int main(void)
{
  foofunc(&x_var);
  x_const = 3;  
  foofunc(&x_const);

  printf("%i,%i\r\n", x_var, x_const); 
  return 0;
}
gcc meint dazu:
consttest.c:14: Fehler: Zuweisung der schreibgeschützten Variable 
»x_const«
consttest.c:15: Warnung: Übergabe des Arguments 1 von »foofunc« entfernt 
Kennzeichner von Zeiger-Ziel-Typ

Lässt man Zeile 14 weg, erhält man zwar ein ausführbares Compilat, das 
aber mit einem "Segmentation fault (core dumped)" abbricht, wohl weil 
man schreibend auf einen schreibgeschützten Bereich zugreifen will. Bei 
einem µC könnte das, wie gesagt, auch das ROM sein.

Eine benannte Konstante belegt also keineswegs automatisch Platz im RAM.

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.