#define Variablen

#742680
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.
#742715
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:
1
#define G ((double)9.81)

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


Peter
Gast #742725
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;
}
#742829
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;
}
Gast #742848
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.
#742855
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.
Persönliche Seite #742900
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
#742992
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:
1
#include <stdio.h>
2

3
const int x_const = 1;
4
      int x_var   = 2;
5

6
void foofunc(int * x)
7
{
8
 *x = 4;
9
}
10

11
int main(void)
12
{
13
  foofunc(&x_var);
14
  x_const = 3;  
15
  foofunc(&x_const);
16

17
  printf("%i,%i\r\n", x_var, x_const); 
18
  return 0;
19
}
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

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