Zeichengröße ('a') in C / C ++

298

Wie groß ist das Zeichen in C und C ++? Soweit ich weiß, beträgt die Größe von char sowohl in C als auch in C ++ 1 Byte.

In C:

#include <stdio.h>
int main()
{
    printf("Size of char : %d\n", sizeof(char));
    return 0;
}

In C ++:

#include <iostream>
int main()
{
    std::cout << "Size of char : " << sizeof(char) << "\n";
    return 0;
}

Keine Überraschungen, beide geben die Ausgabe: Size of char : 1

Jetzt wissen wir , dass Zeichen dargestellt werden als 'a', 'b', 'c', '|', ... Also ich nur die oben genannten Codes auf diese geändert:

In C:

#include <stdio.h>
int main()
{
    char a = 'a';
    printf("Size of char : %d\n", sizeof(a));
    printf("Size of char : %d\n", sizeof('a'));
    return 0;
}

Ausgabe:

Size of char : 1
Size of char : 4

In C ++:

#include <iostream>
int main()
{
    char a = 'a';
    std::cout << "Size of char : " << sizeof(a) << "\n";
    std::cout << "Size of char : " << sizeof('a') << "\n";
    return 0;
}

Ausgabe:

Size of char : 1
Size of char : 1

Warum gibt das sizeof('a')in C und C ++ unterschiedliche Werte zurück?

whacko__Cracko
quelle
8
Das "%|"Format erfordert ein intArgument (oder etwas, das dazu wirbt int). sizeofergibt ein Ergebnis vom Typ size_t. Konvertieren Sie entweder in inteine Besetzung oder verwenden Sie, wenn Ihre Implementierung dies unterstützt "%zu".
Keith Thompson

Antworten:

348

In C ist die Art eines Zeichenkonstante wie 'a'tatsächlich ein int, mit einer Größe von 4 (oder einem anderen implementierungsabhängigen Wert). In C ++ ist der Typ charmit der Größe 1. Dies ist einer von vielen kleinen Unterschieden zwischen den beiden Sprachen.

Eric Postpischil
quelle
12
Im C ++ Standard ist es Abschnitt 2.13.2 / 1, in C 6.4.4.4 zumindest in dem Dokument, das ich habe.
14
+1 (Abgesehen davon, dass die "Größe 4" offensichtlich für die Plattform von nthrgeek gilt, gilt sie jedoch nicht unbedingt für alle Plattformen.)
sbi
28
@nthrgeek: Ich bin zu faul beiden Standards zu zitieren, aber der C ++ Standard hat einen Anhang zu Inkompatibilitäten gewidmet mit C. Unter Anhang C.1.1, erwähnt sie , dass „Art der Zeichenliteral von geändert intzu char, die das Verhalten erklärt. :)
Jalf
3
@nthrgeek: §6.4.4.4, Absatz 10: "Eine Ganzzahlzeichenkonstante hat den Typ int. Der Wert einer Ganzzahlzeichenkonstante, die ein einzelnes Zeichen enthält, das einem Einzelbyte-Ausführungszeichen zugeordnet ist, ist der numerische Wert der Darstellung des zugeordneten Zeichens Zeichen als Ganzzahl interpretiert. "
Stephen Canon
7
@nthrgeek: Sie sollten nicht nach einer Standardreferenz fragen, es sei denn, Sie haben ein Argument zu einem bestimmten Punkt und möchten verstehen, warum die andere Person eine andere Meinung hat. Wenn alle einverstanden sind, akzeptiere es einfach. Sie (als Entwickler) sollten ziemlich intelligent genug sein, um schnell eine gemeinsame Antwort wie diese zu finden.
Martin York
26

Wie Paul sagte, liegt es daran, dass 'a'es ein intin C, aber ein charin C ++ ist.

Ich beschreibe diesen spezifischen Unterschied zwischen C und C ++ in etwas, das ich vor einigen Jahren geschrieben habe: http://david.tribble.com/text/cdiffs.htm

David R Tribble
quelle
4
Nur neugierig, aber arbeiten Sie daran, dieses (sehr detaillierte) Dokument zu aktualisieren, um die neuen Änderungen in C ++ 11 und C11 aufzunehmen?
Adam Rosenfield
Nicht im Moment. Mein Interesse an C und C ++ hat in den letzten fünf Jahren stark nachgelassen.
David R Tribble
3
Äh, ich habe deine Arbeit benutzt, um das zu schreiben und hier bist du auf SO. So eine kleine Welt!
17

In C sind die Zeichenliterale in C ++ int und char . Dies ist in C ++ erforderlich, um das Überladen von Funktionen zu unterstützen . Siehe dieses Beispiel:

void foo(char c)
{
    puts("char");
}
void foo(int i)
{
    puts("int");
}
int main()
{
    foo('i');
    return 0;
}

Ausgabe:

char
Schmied
quelle
5

In der Sprache C ist das Zeichenliteral kein charTyp. C betrachtet das Zeichenliteral als Ganzzahl. Es gibt also keinen Unterschied zwischen sizeof('a')undsizeof(1) .

Die Größe des Zeichenliteral ist also gleich der Größe der Ganzzahl in C.

In der C ++ - Sprache ist das Zeichenliteral der Typ char. Die Referenz sagt:

1) schmales Zeichenliteral oder gewöhnliches Zeichenliteral, zB 'a'oder '\n'oder '\13'. Ein solches Literal hat den Typchar und den Wert, der der Darstellung von c-char im Ausführungszeichensatz entspricht. Wenn c-char im Ausführungszeichensatz nicht als einzelnes Byte dargestellt werden kann, hat das Literal den Typ int und einen implementierungsdefinierten Wert.

In C ++ ist das Zeichenliteral also eine Art von char. Die Größe des Zeichenliteral in C ++ beträgt also ein Byte.

Außerdem haben Sie in Ihren Programmen einen falschen Formatbezeichner für den sizeofOperator verwendet.

C11 §7.21.6.1 (P9):

Wenn eine Konvertierungsspezifikation ungültig ist, ist das Verhalten undefiniert.275) Wenn ein Argument nicht der richtige Typ für die entsprechende Konvertierungsspezifikation ist, ist das Verhalten undefiniert.

Sie sollten also %zustattdessen den Formatbezeichner verwenden %d, da es sich sonst um ein undefiniertes Verhalten in C handelt.

msc
quelle
%zuwird auf vielen Plattformen nicht unterstützt, bietet aber eine bessere Portabilität, Verwendung (int)sizeof(char)und Formatierung%d
chqrlie
Der Wert von Zeichenliteralen ist nicht unbedingt der entsprechende ASCII-Code. Dies hängt von den Quell- und Ausführungszeichensätzen ab und davon, ob der charTyp standardmäßig signiert oder nicht signiert ist.
Chqrlie