Frage

Ich bin ein bisschen verwirrt zwischen dem, was ist und nicht ein konstanter Ausdruck in C, auch nach viel googleing. Könnten Sie ein Beispiel für etwas schaffen, das ist, und das ist nicht, ein konstanter Ausdruck in C?

War es hilfreich?

Lösung

Ein konstanter Ausdruck kann bei der Kompilierung ausgewertet werden. Das heißt es hat keine Variablen drin. Zum Beispiel:

5 + 7 / 3

ist ein konstanter Ausdruck. So etwas wie:

5 + someNumber / 3

nicht, someNumber unter der Annahme ist eine Variable (dh nicht selbst eine Kompilierung-Konstante).

Andere Tipps

Es gibt eine andere Feinheit konstanten Ausdrücke. Es gibt einige Dinge, die mit dem Compiler bekannt sind, können aber nicht an den Präprozessor bekannt sein.

Zum Beispiel (24*60*60) kann durch beide berechnet werden, aber sizeof struct foo nur den Compiler bekannt. Diese Unterscheidung kann wichtig, wenn Sie überprüfen wollen, dass ein struct definiert eine extern beauftragt Größe gerecht zu werden, oder dass seine Mitglieder bei extern angegebenen Offsets abgebildet werden. (Dieser Anwendungsfall tritt häufig auf, wenn Gerätetreiber Codierung, wo die struct Geräteregister als layed aus im Speicherraum beschreibt.)

In diesem Fall kann man einfach nicht #if (sizeof(struct UART) == 12) sagen, weil der Präprozessor auf einem Pass arbeitet vor der Zusammenstellung und einfach kann die Größe von irgendwelchen Typen nicht kennen. Es ist ein konstanter Ausdruck jedoch, und würde als Initialisierer für eine globale Variable (z.B. int UARTwords = sizeof(struct UART) / sizeof(short);) oder zu erklären, um die Größe eines Arrays (z.B. unsigned char UARTmirror[sizeof(struct UART)];)

gültig

Niemand scheint erwähnt haben noch eine andere Art von konstanter Ausdruck: Adreßkonstanten. Die Adresse eines Objekts mit statischer Speicherdauer ist eine Adresse konstant, also Sie Datei Umfang diese Art der Sache tun:

char x;
char *p = &x;

Stringliterale definieren Arrays mit statischer Speicherdauer, so dass diese Regel auch ist, warum diese im Dateigültigkeitsbereich tun können:

char *s = "foobar";

Jeder einwertig wörtliche ist ein konstanter Ausdruck.

3     0.0f    '\n'

(Stringliterale sind seltsam, weil sie tatsächlich Arrays sind. Scheint "hello" nicht wirklich eine Konstante ist, wie es am Ende zu haben verknüpft werden und all das, und die Adresse und die Inhalte können zur Laufzeit geändert werden.)

Die meisten Betreiber (sizeof, Abgüsse, usw.), die auf Konstanten oder Typen sind konstante Ausdrücke.

sizeof(char)
(byte) 15

Jeder Ausdruck, der nur konstante Ausdrücke ist selbst auch ein konstanter Ausdruck.

15 + 3
0.0f + 0.0f
sizeof(char)

Jeder Ausdruck, die Funktionsaufrufe oder nicht konstanten Ausdrücke ist in der Regel nicht ein konstanter Ausdruck.

strlen("hello")
fifteen + x

Jedes Status des Makros als konstanter Ausdruck hängt davon ab, was es erweitert zu.

/* Always a constant */
#define FIFTEEN 15

/* Only constant if (x) is
#define htons(x)  (( ((x) >> 8) | ((x) << 8) ) & 0xffff) 

/* Never constant */
#define X_LENGTH  strlen(x)

Ich hatte ursprünglich ein paar Sachen hier über const Identifikatoren, aber ich getestet, dass und offenbar nicht in C. const gilt, seltsam genug, nicht Konstanten deklarieren (zumindest nicht ones „Konstante“ genug zu sein, in switch Anweisungen verwendet). In C ++, aber es funktioniert.

Eine weiterer Spaß wenig Falten: in C, der Wert eines ‚Enum‘ eine Konstante ist, sondern erst nach der Erklärung des ‚Enum‘ verwendet werden kann, ist abgeschlossen. Die folgende, zum Beispiel, ist nicht akzeptabel in Standard-C, obwohl es akzeptabel ist in C ++:

enum {foo=19, bar, boz=bar+5;};

Es könnte neu geschrieben werden:

enum {foo=19, bar}; enum {boz=bar+5;};

obwohl dies würde mehrere verschiedene Aufzählungstypen am Ende definieren, anstatt eine, die alle Werte enthält.

Auch integral character constants als 'a' oder '\n' Konstanten sind, dass der Compiler als solche erkennt. Sie haben Typ int.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top