Wenn ich Variablen so deklariere: #define G 9.81 Was für einen Datentyp wird den da erzeugt? double, float,..?
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.
ja und wenn ich dann beispielweise eine operation ausführe: 10*G; dann muss das doch irgeindein datentyp sein dass man damit rechnen kann?
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.
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
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.
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; }
@Ralph Der Compiler wird, wenn er einigermassen was taugt, deshalb keine Libs einbinden, denn er wird den Wert schon beim compilieren berechnen!
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; }
@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.
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.
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
@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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.