Datentypen

0

Datentypen – Von Zahlenschubsern, Textprofis und Wahrheitsdetektiven!

Wie im Kapitel „Variablen“ erläutert, muss eine Variable in C einen bestimmten Datentyp haben. Innerhalb der printf() Funktion musst Du einen Formatbezeichner verwenden, um entsprechende Werte auszugeben:

Beispiel

// Variablen anlegen
int myNum = 5;             // Integer (ganze Zahl)
float myFloatNum = 5.99;   // Fließkommazahl
char myLetter = 'D';       // Zeichen

// Ausgabe der Wert
printf("%d\n", myNum);
printf("%f\n", myFloatNum);
printf("%c\n", myLetter);

Grundlegende Datentypen

Der Datentyp gibt die Größe und Art der Informationen an, die in der Variable gespeichert werden.

In diesem Tutorial konzentrieren wir uns auf die grundlegendsten. Mit signed und unsigned kannst du festlegen, ob auch negative Zahlen dabei sein sollen oder nicht. Bei signed sind negative Zahlen möglich, bei unsigned nicht. Die Typen short, int, long und long long sind standardmäßig signed, also vorzeichenbehaftet. Das heißt, ein signed int ist dasselbe wie ein normales int. Wie viel Speicher ein Datentyp braucht, hängt – zumindest in C* – vom Computer ab, auf dem das Programm läuft. Dabei braucht short mindestens 2 Byte, int meist 4, long mindestens 4 und long long mindestens 8 Byte.

* in der Programmiersprache Java haben die Datentypen hingegen eine feste Größe

Datentyp(name)GrößeBeschreibung / WertebereichBeispiel
int2 oder 4 Byteint bzw. signed int:
Speichert ganze Zahlen im Wertebereich von -2 147 483 648 bis 2 147 483 647 (-231…231-1)

unsigned int:
Speichert ganze Zahlen im Wertebereich von
0 bis 4 294 967 295
(0…232-1)

1
float4 ByteGleitkomma-Datentyp, Speichert Dezimalzahlen (mit 6-7 Dezimalstellen)1.99
double8 ByteGleitkomma-Datentyp, Speichert Dezimalzahlen (mit 15 Dezimalstellen)1.99
char1 Bytechar bzw. signed char:
Speichert einzelne Zeichen/Buchstaben/Zahlen im Wertebereich von -128 bis 127 (-27…27-1)

unsigned char:
Speichert einzelne Zeichen/Buchstaben/Zahlen im Wertebereich von 0 bis 255 (0…28-1)
'A'
short2 Byteshort bzw. signed short:
Speichert ganze Zahlen im Wertebereich von
-32768 bis 32767 (-215…215-1)

unsigned short:
Speichert ganze Zahlen im Wertebereich von
0 bis 65535 (0…216-1)
long4 Bytelong bzw. signed long:
Speichert ganze Zahlen im Wertebereich von -2 147 483 648 bis 2 147 483 647 (-231…231-1)

unsigned long:
Speichert ganze Zahlen im Wertebereich von
0 bis 4 294 967 295
(0…232-1)
long long8 Bytelong long bzw. signed long long:
Speichert ganze Zahlen im Wertebereich von –9 223 372 036 854 775 808 … +9 223 372 036 854 775 807 (-263…263-1)

unsigned long long:
Speichert ganze Zahlen im Wertebereich von 0 bis 18 446 744 073 709 551 615
(0…264-1)

Formatbezeichner

Für jeden Datentyp gibt es unterschiedliche Formatbezeichner. Hier sind einige davon:

FormatbezeichnerDatentyp(name) / Beschreibung
%d oder %iint
%ld oder %lilong
%f oder %Ffloat
%lfdouble
%cchar
%oOktale Darstellung des Wertes
%x oder %XHexadezimale Darstellung des Wertes
%schar[]
Wird für Strings – also Zeichenfolgen (Text) – verwendet. Mehr dazu erfährst du in einem späteren Kapitel.

Hinweis: Es ist wichtig, dass Sie den richtigen Formatbezeichner für den angegebenen Datentyp verwenden. Andernfalls kann es zu Fehlern im Programm kommen oder das Programm kann sogar abstürzen.

Der char Typ

Der char Datentyp wird zum Speichern eines einzelnen Zeichens (engl. character) verwendet.

Das Zeichen muss von einfachen Anführungszeichen umgeben sein, etwa ‚A‘ oder ‚c‘. Wir können den Formatbezeichner %c nutzen, um das Zeichen auszugeben:

Beispiel

char meinA = 'A';
printf("%c", meinA);

Wenn Du mit ASCII vertraut bist, kannst Du alternativ ASCII-Werte verwenden, um bestimmte Zeichen anzuzeigen. Beachte, dass diese Werte nicht in Anführungszeichen ('') eingeschlossen sind, da es sich um Zahlen handelt:

Beispiel

char a = 65, b = 66, c = 67;
printf("%c", a);
printf("%c", b);
printf("%c", c);

Hinweise zu char

Wenn Du versuchst mehr als ein einzelnes Zeichen zu speichern, dann wird nur das letzte Zeichen ausgegeben:

Beispiel

char meinText = 'Hallo';
printf("%c", meinText);

Hinweis: Verwende den Typ char nicht zum Speichern mehrerer Zeichen, da dies zu Fehlern führen kann.

Um mehrere Zeichen (oder ganze Wörter) zu speichern, verwende Zeichenfolgen (mehr dazu in einem späteren Kapitel):

Beispiel

char meinText[] = "Hallo";
printf("%s", meinText);

Für den Moment genügt es zu wissen, dass wir Zeichenfolgen zum Speichern mehrerer Zeichen/Texte und den Zeichentyp char für einzelne Zeichen verwenden.

Numerische Typen

In C solltest Du int verwenden, wenn Du eine ganze Zahl ohne Nachkommastellen speichern willst, zum Beispiel 35 oder 1000. Wenn Du dagegen eine Zahl mit Nachkommastellen brauchst, wie 9.99 oder 3.1415, dann solltest Du float oder double verwenden.

int

int meineZahl = 1000;
printf("%d", meineZahl);

float

float meineZahl = 5.75;
printf("%f", meineZahl);

double

double meineZahl = 19.99;
printf("%lf", meineZahl);

float und double

Die Genauigkeit eines Gleitkommawertes gibt an, wie viele Stellen nach dem Dezimalpunkt gespeichert werden können. Bei float-Variablen sind das etwa sechs bis sieben Dezimalstellen, während double-Variablen etwa 15 Dezimalstellen genau speichern können. Daher ist es bei den meisten Berechnungen oft sicherer, double zu verwenden. Allerdings braucht double doppelt so viel Speicher wie float (8 Byte statt 4 Byte).

Wissenschaftliche Notation

In C kannst Du sehr große oder sehr kleine Zahlen mithilfe der wissenschaftlichen Notation darstellen. Dabei wird eine Zahl als Produkt einer Basis und einer Potenz von 10 geschrieben. Zum Beispiel wird 5.3e3 als 5.3 × 10³ interpretiert, was 5300 entspricht. Das „e“ steht für „exponent“, und der Wert dahinter gibt an, wie oft die Zahl mit 10 multipliziert (positiver Exponent) oder durch 10 geteilt (negativer Exponent) wird. Zum Beispiel ist 1.2e-4 gleich 1.2 × 10⁻⁴, also 0.00012.

In C kannst Du die wissenschaftliche Notation sowohl mit float als auch mit double verwenden.

Beispiel

float f1 = 35e3;
double d1 = 12E4;

printf("%f\n", f1);
printf("%lf", d1);

Anzahl der Nachkommastellen festlegen

Du hast vielleicht bemerkt, dass bei der Ausgabe von Gleitkommazahlen oft viele Nachkommastellen erscheinen. In C kannst Du jedoch selbst bestimmen, wie viele Stellen nach dem Komma angezeigt werden.

Beispiel

float meineFloatZahl = 3.5;
double meineDoubleZahl = 19.99;

printf("%f\n", meineFloatZahl); // Ausgabe: 3.500000
printf("%lf", meineDoubleZahl); // Ausgabe: 19.990000

Wenn Du die zusätzlichen Nullen weglassen möchtest (dies nennt man auch „die Dezimalgenauigkeit festlegen“), kannst Du einen Punkt (.) gefolgt von einer Zahl verwenden, die angibt, wie viele Stellen nach dem Komma angezeigt werden sollen:

Beispiel

float meineFloatZahl = 3.5;

printf("%f\n", meineFloatZahl); // Zeigt standardmässig 6 Ziffern nach dem Komma an
printf("%.1f\n", meineFloatZahl); // Zeigt nur 1 Ziffern
printf("%.2f\n", meineFloatZahl); // Zeigt nur 2 Ziffern
printf("%.4f", meineFloatZahl);   // Zeigt nur 4 Ziffern

Holen Sie sich die Speichergröße

Im Kapitel Datentypen haben wir bereits festgestellt, dass die Speichergröße einer Variablen je nach Typ variiert:

DatentypGröße
int2 oder 4 bytes
float4 bytes
double8 bytes
char1 byte

Die Speichergröße gibt an, wie viel Platz ein Typ im Arbeitsspeicher des Computers einnimmt.

Um die tatsächliche Größe (in Bytes) eines Datentyps oder einer Variablen zu ermitteln, verwende die Funktion sizeof():

Beispiel

int myInt;
float myFloat;
double myDouble;
char myChar;

printf("%lu\n", sizeof(myInt));
printf("%lu\n", sizeof(myFloat));
printf("%lu\n", sizeof(myDouble));
printf("%lu\n", sizeof(myChar));

Beachte, dass wir zum Drucken des Ergebnisses den Formatbezeichner %lu anstelle von %d verwenden. Dies liegt daran, dass der Compiler erwartet, dass der Operator sizeof eine lange vorzeichenlose int (%lu) anstelle von int (%d) zurückgibt. Auf einigen Computern funktioniert es möglicherweise mit %d, aber es ist sicherer, %lu zu verwenden.

Warum sollte ich die Größe von Datentypen kennen?

Die Kenntnis der Größe verschiedener Datentypen ist wichtig, da sie etwas über die Speichernutzung und Leistung aussagt.

Beispielsweise beträgt die Größe eines Char Typs 1 Byte. Das bedeutet, dass ein Array mit 1000 Char Werten 1000 Byte (1 KB) Speicher belegt.

Die Verwendung des richtigen Datentyps für den richtigen Zweck spart Speicher und verbessert die Leistung Deines Programms.

Später in diesem Tutorial erfährst Du mehr über den Sizeof Operator und wie Du ihn in verschiedenen Szenarien verwenden kannst.

Beispiel aus dem echten Leben

Hier ist ein Beispiel aus der Praxis für die Verwendung verschiedener Datentypen zum Berechnen und Ausgeben der Gesamtkosten einer Reihe von Artikeln:

Beispiel

// Create variables of different data types
int items = 50;
float cost_per_item = 9.99;
float total_cost = items * cost_per_item;
char currency = '$';

// Print variables
printf("Number of items: %d\n", items);
printf("Cost per item: %.2f %c\n", cost_per_item, currency);
printf("Total cost = %.2f %c\n", total_cost, currency);

Typkonvertierung

Manchmal müssen Sie den Wert eines Datentyps in einen anderen Typ konvertieren. Dies wird als Typkonvertierung bezeichnet.

Wenn Du beispielsweise versuchst, zwei Ganzzahlen zu dividieren, nämlich 5 durch 2, würdest Du als Ergebnis 2,5 erwarten. Da wir aber mit Ganzzahlen (und nicht mit Fließkommawerten) arbeiten, gibt das folgende Beispiel nur 2 aus:

Beispiel

int x = 5;
int y = 2;
int sum = 5 / 2;

printf("%d", sum); // Outputs 2

Um das richtige Ergebnis zu erhalten, musst Du wissen, wie die Typkonvertierung funktioniert.

In C gibt es zwei Arten der Konvertierung:

  • Implizite Konvertierung (automatisch)
  • Explizite Konvertierung (manuell)

Implizite Konvertierung

Die implizite Konvertierung wird automatisch vom Compiler durchgeführt, wenn Du einen Wert eines Typs einem anderen zuweist.

Wenn Du beispielsweise einem Float-Typ einen Int-Wert zuweist:

Beispiel

// Automatic conversion: int to float
float myFloat = 9;

printf("%f", myFloat); // 9.000000

Wie Du siehst, konvertiert der Compiler den Int-Wert 9 automatisch in einen Float-Wert von 9.000000.

Dies kann riskant sein, da Du in bestimmten Situationen die Kontrolle über bestimmte Werte verlieren könntest.

Insbesondere wenn es andersherum wäre – das folgende Beispiel wandelt den Float Wert 9,99 automatisch in einen Int Wert von 9 um:

Beispiel

// Automatic conversion: float to int
int myInt = 9.99;

printf("%d", myInt); // 9

Was ist mit .99 passiert? Wir brauchen diese Daten vielleicht in unserem Programm! Sei also vorsichtig. Es ist wichtig, dass Du weißt, wie der Compiler in diesen Situationen arbeitet, um unerwartete Ergebnisse zu vermeiden.

Ein weiteres Beispiel: Wenn Du zwei Ganzzahlen dividierst, nämlich 5 durch 2, weißt Du, dass die Summe 2,5 ist. Und wie Du vom Anfang dieser Seite weißt, wird das Ergebnis nur die Zahl 2 anzeigen, wenn Du die Summe als Ganzzahl speicherst. Daher wäre es besser, die Summe als Float oder Double zu speichern, oder?

Beispiel

float sum = 5 / 2;

printf("%f", sum); // 2.000000

Warum is das Ergebnis 2.00000 und nicht 2.5? Nun ja, weil 5 and 2 während der Division noch Integer sind. In diesem Fall musst Du die Werte 5 und 2 manuell in float konvertieren, sodass zwei float-Werte dividiert werden und damit auch ein float-Wert als Ergebnis entsteht.

Explizite Konvertierung

Die explizite Konvertierung erfolgt manuell, indem der Typ in Klammern () vor den Wert gesetzt wird.

Wenn wir unser Problem aus dem obigen Beispiel betrachten, können wir nun das richtige Ergebnis erhalten:

Beispiel

// manuelle Umwandlung: int zu float
float sum = (float) 5 / 2;

printf("%f", sum); // 2.500000

Du kannst den Typ auch vor eine Variable setzen:

Beispiel

int num1 = 5;
int num2 = 2;
float sum = (float) num1 / num2;

printf("%f", sum); // 2.500000

Und da Du im vorigen Kapitel etwas über „Dezimalgenauigkeit“ gelernt hast, kannst Du die Ausgabe noch übersichtlicher gestalten, indem Du die zusätzlichen Nullen entfernst (falls Du möchtest):

Beispiel

int num1 = 5;
int num2 = 2;
float sum = (float) num1 / num2;

printf("%.1f", sum); // 2.5

Beispiel aus dem echten Leben

Hier ist ein Beispiel aus dem echten Leben für Datentypen und Typkonvertierung, bei dem wir ein Programm erstellen, um den Prozentsatz der Punktzahl eines Benutzers im Verhältnis zur Höchstpunktzahl in einem Spiel zu berechnen:

Beispiel

// Maximale Punktzahl, die im Spiel erreichbar ist
int maxPunkte = 500;

// Punktzahl des Nutzers
int punkte = 423;

/* Berechne den Prozentsatz der Punktzahl des Benutzers im Verhältnis zur maximal erreichbaren Punktzahl.
Dabei punkte in float umwandeln, um sicherzustellen, dass die Division genau ist */
float prozent = (float) punkte / maxPunkte * 100.0;

// Prozente der erreichten Punktzahl ausgeben
printf("Prozent der erreichten Punkte ist %.2f", prozent);
Nach oben scrollen