Ich bin ein bisschen verwirrt zwischen dem, was ein konstanter Ausdruck in C ist und nicht ist, selbst nach viel Googleing. Könntest du ein Beispiel für etwas geben, das ein konstanter Ausdruck in C ist und was nicht?
Ein konstanter Ausdruck kann zur Kompilierzeit ausgewertet werden. Das bedeutet, dass es keine Variablen enthält. Zum Beispiel:
%Vor%ist ein konstanter Ausdruck. Etwas wie:
%Vor% ist nicht, unter der Annahme, dass someNumber
eine Variable ist (dh nicht selbst eine Kompilierzeitkonstante).
Es gibt eine weitere Subtilität für konstante Ausdrücke. Es gibt einige Dinge, die dem Compiler bekannt sind, aber dem Präprozessor nicht bekannt sein können.
Zum Beispiel kann (24*60*60)
von beiden berechnet werden, aber sizeof struct foo
ist nur dem Compiler bekannt. Diese Unterscheidung kann wichtig sein, wenn Sie überprüfen möchten, ob eine struct
definiert ist, um eine extern vorgeschriebene Größe zu erfüllen, oder dass ihre Mitglieder externen Offsets zugeordnet sind. (Dieser Anwendungsfall tritt häufig bei der Kodierung von Gerätetreibern auf, bei denen% code_de Geräteregister so beschreibt, wie sie im Speicherbereich angeordnet sind.)
In diesem Fall kann man nicht einfach struct
sagen, weil der Präprozessor einen Durchlauf vor der Kompilierung ausführt und einfach die Größe irgendwelcher Typen nicht kennen kann. Es ist jedoch ein konstanter Ausdruck und wäre als Initialisierer für eine globale Variable gültig (z. B. #if (sizeof(struct UART) == 12)
) oder um die Größe eines Arrays zu deklarieren (z. B. int UARTwords = sizeof(struct UART) / sizeof(short);
)
Niemand scheint eine andere Art von konstantem Ausdruck erwähnt zu haben: Adresskonstanten. Die Adresse eines Objekts mit statischer Speicherdauer ist eine Adresskonstante, daher können Sie dies im Dateibereich tun:
%Vor%String-Literale definieren Arrays mit statischer Speicherdauer. Diese Regel ist daher auch der Grund, warum Sie dies im Dateibereich tun können:
%Vor%Jedes einwertige Literal ist ein konstanter Ausdruck.
%Vor% (String-Literale sind seltsam, weil sie eigentlich Arrays sind. Scheint, dass "hello"
nicht wirklich eine Konstante ist, da sie letztendlich verlinkt werden muss, und die Adresse und der Inhalt können sich zur Laufzeit ändern.)
Die meisten Operatoren (sizeof, casts usw.), die auf Konstanten oder Typen angewendet werden, sind konstante Ausdrücke.
%Vor%Jeder Ausdruck, der nur konstante Ausdrücke enthält, ist selbst auch ein konstanter Ausdruck.
%Vor%Jeder Ausdruck, der Funktionsaufrufe oder nicht konstante Ausdrücke enthält, ist normalerweise nicht ein konstanter Ausdruck.
%Vor%Der Status eines Makros als konstanter Ausdruck hängt davon ab, auf was er expandiert.
%Vor% Ich hatte ursprünglich einige Sachen über const
identifiers hier, aber ich habe das getestet und anscheinend gilt es nicht in C. const
, seltsam genug, deklariert keine Konstanten (zumindest keine "konstant" "Genug, um in switch
Statements verwendet zu werden." In C ++ jedoch tut es das.
Noch ein lustiger kleiner Kniff: In C ist der Wert eines 'Enums' eine Konstante, aber er darf nur verwendet werden, nachdem die Deklaration des 'Enums' abgeschlossen ist. Das Folgende ist zum Beispiel in Standard C nicht akzeptabel, obwohl es in C ++ akzeptabel ist:
%Vor%Es könnte neu geschrieben werden:
%Vor%Dies würde jedoch dazu führen, dass mehrere verschiedene Aufzählungstypen definiert werden und nicht alle, die alle Werte enthalten.
Auch integral character constants
als 'a'
oder '\n'
sind Konstanten, die der Compiler als solche erkennt. Sie haben den Typ int
.
Tags und Links c constant-expression