Ich habe einen kleinen Code über den sizeof
Operator mit dem ternären Operator:
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a = true;
printf("%zu\n", sizeof(bool)); // Ok
printf("%zu\n", sizeof(a)); // Ok
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
return 0;
}
Ausgabe ( GCC ):
1
1
4 // Why 4?
Aber hier,
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
Der ternäre Operator gibt den boolean
Typ zurück und die Größe des bool
Typs ist 1
Byte in C.
Dann warum sizeof(a ? true : false)
eine Leistung von vier Bytes geben?
sizeof(true)
undsizeof(false)
ist auch 4: ide.geeksforgeeks.org/O5jvuN_Bool
, Größe 1 zu haben, aber nichttrue
undfalse
. Aber der Standard hat dazu nichts zu sagen, soweit ich das beurteilen kann.char a;
sizeof(a) == 1
undsizeof('a') == sizeof(int)
(in C). Es geht nicht um die Implementierung, es geht um die Sprache.sizeof(true)
? Vielleicht wird es die Ausdünnung etwas klarer machen (insbesondere wird es offensichtlich, dass der ternäre Operator ein roter Hering ist).true
ist#define
d von 1,stdbool.h
also ja, dies ist die wörtliche Definition.Antworten:
Es ist, weil du hast
#include <stdbool.h>
. Dieser Header definiert Makrostrue
undfalse
sein1
und0
, also sieht Ihre Aussage folgendermaßen aus:sizeof(int)
ist 4 auf Ihrer Plattform.quelle
sizeof(a ? (uint8_t)1 : (uint8_t)0);
würde auch ein Ergebnis von 4 ergeben. Die ganzzahlige Förderung der?:
Operanden ist hier der wichtige Teil, nicht die Größe vontrue
undfalse
.int
ohne Werbung. Der Grund, warum Sie es nicht "reparieren" können, sind die Standardaktionen.true
undfalse
ist nicht Makros; Sie sind Schlüsselwörter. Sie sind nicht als1
und definiert0
, sondern als wahre und falsche Werte desbool
Typs.sizeof(true)
ist 1. Demo .OK, da steckt noch mehr dahinter!
In C ist das Ergebnis dieser ternären Operation vom Typ
int
. [Anmerkungen unten (1,2)]Daher ist das Ergebnis dasselbe wie der Ausdruck
sizeof(int)
auf Ihrer Plattform.Anmerkung 1: Zitieren
C11
, Kapitel §7.18,Boolean type and values <stdbool.h>
Anmerkung 2: Für den bedingten Operator Kapitel §6.5.15 ( Hervorhebung meiner )
und
Daher ist das Ergebnis vom Typ Integer, und aufgrund des Wertebereichs sind die Konstanten genau vom Typ
int
.Ein allgemeiner Rat
int main()
sollte jedoch besser seinint main (void)
, wirklich standardkonform zu sein.quelle
<stdbool.h>
definiert die MACROS als vom Typint
.. ist das falsch?Der ternäre Operator ist ein roter Hering.
druckt 4 (oder was auch
sizeof(int)
immer auf Ihrer Plattform ist).Im Folgenden wird davon ausgegangen, dass dies
bool
ein Synonym fürchar
oder ein ähnlicher Typ der Größe 1 ist undint
größer als istchar
.Der Grund warum
sizeof(true) != sizeof(bool)
undsizeof(true) == sizeof(int)
ist einfach, weiltrue
es kein Ausdruck des Typs istbool
. Es ist ein Ausdruck des Typsint
. Es ist#define
d wie1
instdbool.h
.Bearbeiten: Dieser Absatz ist nicht wahr, Argumente, zu denenbool
In C gibt es überhaupt keine Werte vom Typ . Jeder solche Wert wird sofort gefördertint
, auch wenn er als Argument verwendet wirdsizeof
.sizeof
nicht befördert werden sollint
. Dies hat jedoch keinen Einfluss auf die Schlussfolgerungen.quelle
(bool)1
ein Wert vom Typbool
?printf("%u\n", sizeof((char) 1));
druckt1
auf meiner Plattform, währendprintf("%u\n", sizeof(1));
druckt4
. Bedeutet dies nicht, dass Ihre Aussage "Jeder solche Wert wird sofort zu int befördert, auch wenn er als Argument für sizeof verwendet wird" falsch ist?true
etc spielt im Fall von keine Rolle,?:
da die Ganzzahlint
sowieso hochgestuft wird. Das heißt, die Antwort sollte sich mit der Frage befassen, warum?:
es sich um einen roten Hering handelt.In Bezug auf den Booleschen Typ in C.
Ein boolescher Typ wurde ziemlich spät in der C-Sprache eingeführt, im Jahr 1999. Zuvor hatte C keinen booleschen Typ, sondern wurde
int
für alle booleschen Ausdrücke verwendet. Daher geben alle logischen Operatoren wie> == !
etc einenint
Wert von1
oder zurück0
.Es war für Anwendungen üblich, hausgemachte Typen wie zu verwenden
typedef enum { FALSE, TRUE } BOOL;
, die sich auch aufint
Typen in Größengröße beschränken.C ++ hatte einen viel besseren und expliziten booleschen Typ
bool
, der nicht größer als 1 Byte war. Während die booleschen Typen oder Ausdrücke in C im schlimmsten Fall als 4 Bytes enden würden. In C wurde eine gewisse Kompatibilität mit C ++ mit dem C99-Standard eingeführt. C bekam dann einen booleschen Typ_Bool
und auch den Headerstdbool.h
.stdbool.h
bietet einige Kompatibilität mit C ++. Dieser Header definiert das Makrobool
(gleiche Schreibweise wie das C ++ - Schlüsselwort), das erweitert_Bool
wird. Dieser Typ ist ein kleiner Ganzzahltyp, wahrscheinlich 1 Byte groß. In ähnlicher Weise enthält der Header zwei Makrostrue
und diefalse
gleiche Schreibweise wie C ++ - Schlüsselwörter, jedoch mit Abwärtskompatibilität zu älteren C-Programmen . Dahertrue
undfalse
erweitern Sie zu1
und0
in C und deren Typ istint
. Diese Makros sind nicht vom booleschen Typ, wie es die entsprechenden C ++ - Schlüsselwörter wären.In ähnlicher Weise aus Gründen der Abwärtskompatibilität, logische Operatoren in C noch zurückkehren ein
int
bis heute, obwohl heutzutage C einen Booleschen Typ bekam. In C ++ geben logische Operatoren a zurückbool
. Ein Ausdruck wiesizeof(a == b)
gibt also die Größe von aint
in C an, aber die Größe von abool
in C ++.In Bezug auf den bedingten Operator
?:
Der bedingte Operator
?:
ist ein seltsamer Operator mit ein paar Macken. Es ist ein häufiger Fehler zu glauben, dass es zu 100% äquivalent zu istif() { } else {}
. Nicht ganz.Es gibt einen Sequenzpunkt zwischen der Auswertung des 1. und des 2. oder 3. Operanden. Es
?:
wird garantiert, dass der Operator nur den 2. oder 3. Operanden auswertet, sodass er keine Nebenwirkungen des Operanden ausführen kann, die nicht ausgewertet werden. Code wietrue? func1() : func2()
wird nicht ausgeführtfunc2()
. So weit, ist es gut.Es gibt jedoch eine spezielle Regel, die besagt, dass der 2. und 3. Operand implizit vom Typ heraufgestuft und mit den üblichen arithmetischen Konvertierungen gegeneinander abgewogen werden müssen . ( Implizite Typ-Promotion-Regeln in C hier erklärt ). Dies bedeutet, dass der 2. oder 3. Operand immer mindestens so groß wie ein ist
int
.Es spielt also keine Rolle
true
und istfalse
zufällig vom Typint
in C, da der Ausdruck immer mindestens die Größe einesint
Egal ergibt .Selbst wenn Sie den Ausdruck neu schreiben würden, würde er immer noch die Größe eines !
sizeof(a ? (bool)true : (bool)false)
int
Dies liegt an der impliziten Typwerbung durch die üblichen arithmetischen Konvertierungen.
quelle
sizeof(bool)==1
.Schnelle Antwort:
sizeof(a ? true : false)
Ergibt4
weiltrue
undfalse
definiert sind<stdbool.h>
als1
und0
jeweils so die Expression Expandiert zusizeof(a ? 1 : 0)
dem mit Typ eine ganze Zahl Ausdruck istint
, die 4 Bytes von der Plattform einnimmt. Aus dem gleichen Grundsizeof(true)
würde auch4
auf Ihrem System ausgewertet .Beachten Sie jedoch Folgendes:
sizeof(a ? a : a)
wird auch ausgewertet,4
weil der ternäre Operator die ganzzahligen Heraufstufungen für seinen zweiten und dritten Operanden ausführt, wenn es sich um ganzzahlige Ausdrücke handelt. Das gleiche passiert natürlich fürsizeof(a ? true : false)
undsizeof(a ? (bool)true : (bool)false)
, aber das Casting des gesamten Ausdrucksbool
verhält sich wie erwartet :sizeof((bool)(a ? true : false)) -> 1
.Beachten Sie auch, dass Vergleichsoperatoren boolesche Werte auswerten
1
oder0
, aber denint
Typ haben :sizeof(a == a) -> 4
.Die einzigen Operatoren, die die Boolesche Natur von beibehalten,
a
wären:der Komma-Operator: beides
sizeof(a, a)
undsizeof(true, a)
zur1
Kompilierungszeit auswerten .die Zuweisungsoperatoren: beide
sizeof(a = a)
undsizeof(a = true)
haben einen Wert von1
.die Inkrementoperatoren:
sizeof(a++) -> 1
Schließlich gilt alles oben Genannte nur für C: C ++ hat unterschiedliche Semantiken in Bezug auf
bool
Typ, Boolesche Wertetrue
undfalse
Vergleichsoperatoren sowie den ternären Operator: Alle diesesizeof()
Ausdrücke werden1
in C ++ ausgewertet .quelle
true
und welchefalse
sind, da die?:
Operanden ohnehin zu einer Ganzzahlint
heraufgestuft würden. Somitsizeof(a ? (uint8_t)true : (uint8_t)false)
ergibt sich auch 4 als Ergebnis.int
Hier ist ein Ausschnitt, aus dem die Quelle stammt
Es gibt Makros
true
undfalse
werden als 1 bzw. 0 deklariert.In diesem Fall ist der Typ jedoch der Typ der Literalkonstanten. Sowohl 0 als auch 1 sind ganzzahlige Konstanten, die in ein int passen, daher ist ihr Typ int.
und das
sizeof(int)
in deinem Fall ist 4.quelle
In C gibt es keinen booleschen Datentyp. Stattdessen werden logische Ausdrücke zu ganzzahligen Werten ausgewertet,
1
wenn dies nicht der Fall ist0
.Bedingte Ausdrücke wie
if
,for
,while
oderc ? a : b
eine ganze Zahl erwarten, wenn die Zahl nicht Null ist zu berücksichtigen ist mittrue
Ausnahme einiger Sonderfälle, hier ist eine rekursive Summe Funktion , bei der der ternäre-Operator auswerten wird ,true
bis zun
erreichen0
.Es kann auch verwendet werden,
NULL
um einen Zeiger zu überprüfen. Hier ist eine rekursive Funktion, die den Inhalt einer einfach verknüpften Liste druckt.quelle