Woher weiß ich welchen Datentyp ich verwenden soll?

6 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Du verwendest grundsätzlich die Datentypen, die am besten geeignet sind. Und was genau "geeignet" bedeutet, hängt vom Einzelfall ab. :)

Als grobe Richtlinien kannst du folgende Hinweise beachten, die sich wohlgemerkt nicht ausschließlich auf die reinen Typen beziehen:

  • Keine Gleitkommatypen als Zählvariablen in Schleifen verwenden.
  • Niemals Gleitpunkttypen mit "==" vergleichen.
  • Variablen (egal welchen Typs) immer als "const" deklarieren, falls diese später nicht mehr geändert werden. Das gleiche gilt für Funktionsparameter. "Recycling" von Variablen vermeiden.
  • Ganzzahltypen immer so klein wie möglich wählen, aber so, dass der höchstmögliche Wert des vorliegenden Anwendungsfalls immer noch darin Platz findet.
  • Vorzeichenbehaftete Typen nur dann nutzen, wenn Vorzeichen auch benötigt werden.
  • Bei einer Division von Vorzeichenbehafteten Ganzzahlen nicht nur darauf prüfen, ob der Divisor Null ist, sondern auch, ob dieser den Kleinstmöglichen Wert darstellt. (Im Falle von "int" wäre das dann INT_MIN aus <limits.h>)
  • "char" oder "int" (auch als "unsigned") verwenden, wenn es auf Geschwindigkeit ankommt. (siehe dazu auch die [u]int_fastX_t Typdefinitionen aus <stdint.h>)
  • Einen Index mit kleinem Typen (z. B. "unsigned char") in eine Tabelle einem "dicken" Zeiger vorziehen, vor allem, wenn es sehr viele davon gibt. (z. B. Bitmaps mit Farbpalette)
  • Eventuell Festkomma-Aritmetik mit stinknormalen Integern in Betracht ziehen.
  • Falls nötig, Bibliotheken für sehr große Typen mit beliebiger Genauigkeit nutzen. (gibt es sowohl für Ganz- als auch Gleitpunktzahlen)
  • Unter Umständen mit Nibbles und Shifting / Maskierungen arbeiten, wenn es auf Speicherplatz ankommt. (Denke auch an Dinge wie BCD-Zahlen.)
  • Nicht vergessen, dass es auch (nicht Standard-C) Minifloats (oft 8 oder 16 Bit breit) und Gleitpunkttypen mit erweiterter Genauigkeit (meist 80 oder 128 Bit breit) gibt, je nach Compiler- und Plattform-Unterstützung.
  • Nutze für weitestgehende Plattformunabhängigkeit die Typdefinitionen aus <stdint.h>, falls du nicht auf ein eingeschränktes Subset von C angewiesen bist.
  • Verwende NIEMALS wchar_t von C++. (falls du nach C irgendwann mal auf C++ umsattelst)
  • Die Schlüsselwörter "auto", "volatile" und "register" nicht nutzen, es sei denn, du weißt genau, dass diese veraltet sind, was sie bedeuten, und kannst Nebeneffekte einschätzen.
  • Lerne die Eigenheiten und Unterschiede von / zwischen Zeigern und Arrays.
  • Beschäftige dich damit, was Speicherklassen sind, wie Paging funktioniert, was W^X oder ASLR heißt, was ein Program-Break ist und denke immer daran, dass es neben Stack und Heap auch noch allerhand "andere" Segmente gibt.
  • Informiere dich, was ptrdiff_t aus <stddef.h> mit void-Zeigern zu tun hat.
  • Setze das "restrict" Schlüsselwort sinnvoll ein, wenn du mit Puffern arbeitest.

... das sind aber alles keine feststehenden Naturgesetze, und u. U. kann / sollte / darf / muss man dagegen verstoßen. Mit der Zeit wirst du ein Gefühl dafür bekommen.

Viele der obigen Punkte werden ich jetzt vermutlich erschlagen, aber du musst diese (noch lange nicht vollständige!) Liste ja auch nicht an einem Abend durchackern. :)

Ich weiß, dass Code-Beispiele mehr als tausend Worte sagen, aber ich habe jetzt keine Zeit mehr, mir zu jedem der obigen Punkte ein Snippet aus den Fingern zu saugen. Falls noch Fragen offen sind, und ich nicht auf Kommentare reagieren sollte (habe in letzter Zeit viel zu tun) stell hier einfach direkt auf GF noch eine weitere Frage zu dem Thema ... irgendjemand wird dir schon Antworten. :)

Viel Spaß! :)

TeeTier  09.05.2018, 20:17

PS: Du solltest auch lernen, wie IEEE 754 Gleitpunktzahlen funktionieren, was Bit- und Bytereihenfolge bedeutet, welche Möglichkeiten es neben Zweier-Komplement noch so für die Darstellung von vorzeichenbehafteten Ganzzahlen gibt, was der Unterschied zwischen Byte und Oktett ist, was man unter MSB und LSB versteht und welche Untertypen es davon noch so gibt, was die EBCDIC-Zeichensätze von ASCII unterscheidet, wie Unicode insbesondere UTF-8/16/32 funktioniert und was es sonst noch so gibt, und und und ...

Naja, vermutlich hast du jetzt genügend Stichworte, um die nächsten zwei Tage mit Google und Wikipedia zu verbringen. Vieles vom Genannten hat nur indirekt etwas mit den C-Datentypen zu tun, aber ALLES davon wird dir bei der C-Programmierung früher oder später sehr sehr weiterhelfen. Lass dich nicht abschrecken, ist alles halb so wild! :)

0

Das entscheidet man immer je nach dem Format der Daten und je nach Programmiersprache. Ich bezieh mich jetzt mal auf Java:

Integer werden meist für Ganzzahlen benutzt und können 2^32 Bit an Daten enthalten - das heißt, Zahlen von -2147483648 bis 2147483647.

Für mehr bräuchtest du entweder long oder BigInt, aber für das meiste reicht int aus.

Brauchst du Nachkommastellen, nimmt man long oder double - je nachdem, welche Genauigkeit man nach dem Komma braucht oder wie groß die Werte sind.

Intern werden diese nach dem IEEE 754-Standard gespeichert - bei float als 32-bit, bei double als 64-bit-Zahl.

Chars sind die ASCII-Repräsentation von einzelnen Zeichen


Kiboman  09.05.2018, 18:26
Integer werden meist für Ganzzahlen benutzt und können 2^32 Bit an Daten enthalten - das heißt, Zahlen von -2147483648 bis 2147483647.

Unterscheidet Java nicht zwischen (nicht)/Vorzeichen behaftet?

0
xxxcyberxxx  09.05.2018, 18:32
@Kiboman

nein, in Java gibt es keine unsigned int.

Auf C/C++ wollte ich nicht ansprechen, da dort int je nach Prozessorarchitektur eine andere Anzahl an bits speichert und man dort dann auf z.B. int32 für das gleiche Ergebnis zurückgreifen sollte.

Aber du hast recht, das gibt es auch - deshalb hab ich den Hinweis mit "und je nach Programmiersprache" gebracht.

2

Ja. Mach es Dir einfach. Und nichts verbiegen.

Man kann mit einem char zählen, denn letztlich steht dahinter nur eine Zahl mit 8 (oder mehr) Bit. Aber: Ein "char" bedeutet "character", also "Zeichen". Also nimm es dafür. Und Zeichenketten sind dann Aneinanderreihungen von chars, die nennt man Strings.

Float heißt Fließkomma oder kurz "Zahl mit Komma, die sich fließend dem Bedarf anpasst", denn das Komma steht nicht an einer bestimmten Position. Wenn Du keine Kommazahlen brauchst, dann vermeide sie, denn sie sind ungenau (ab einer gewissen Kommastelle), es kommt zu Rundungsfehlern, die Verarbeitung ist langsam. Und: Teste bei Kommazahlen im Programm wegen dieser Macken niemals auf Gleichheit. Du weist doch: 1,99999... ist ungleich 2, also testet man auf kleiner-gleich oder größer-gleich. Wenn Du Kommazahlen dagegen brauchst - dann nimm sie.

Für alles andere benutzt man integer (Ganzzahlen).

Bleibt noch die Frage, ob single oder double oder so: Überlege, welches die größte und welches die kleinste Zahl ist, welche Du brauchst. Dann nimm jenen Typ, der das speichern kann. Also wenn Du Zahlen zwischen 0 und 50.000 speichern willst, dann ist eine 16-Bit-Zahl offensichtlich zu klein (nur 0...65535 oder mit Vorzeichen -32768...32767), also benötigst Du mehr als 2 Byte - auf heutigen Systemen also 4 Byte genannt integer. Und irgendwo bei 2 Milliarden solltest Du wieder hellhörig werden, weil dann ein 4-Byte-Integer auch nicht ausreicht. Ansonsten ist ein int immer eine gute Wahl.

Also: Ein Datentyp ist nichts weiter als das Karokästchen auf Deinem Papier: Wenn Du 5 Kästchen umrandest, kannst Du 5 Ziffern hineinschreiben. Brauchst Du eine größere Zahl, umrande vorher(!) mehr Kästchen - denn hinterher sieht es blöd aus. Brauchst Du eine Kommazahl, dann nimm sie, brauchst Du sie nicht, dann lass es.

character ist ein Buchstabe. Brauchst du ganz klar, wenn du Strings (Zeichenketten) dir bauen willst.

Integer ist ein ganzzahliger Datentyp. Den nimmst du standardmäßig immer, wenn es irgendwie um zahlen, zählen, durchzählen, rechnen geht.

Nur wenn die spezielle Antwort auf die Frage "brauch ich vielleicht fließkommazahlen, weil ich die Wurzel von 2 ausgeben will?", dann nimmsxt du floats.

Man sollte auf keinen Fall irgendwie immer floats zum rechnen nehmen. 1) Kann man mit Floats keine Restrechnungen anstellen (Modulo) und 2) werden für die arithmetischen Operationen mit Fließkommazahlen in der ALU (im Prozessor) ganz andere Rechenregister genutzt. Fließkommaberechnungen brauchen deutlich länger als Ganzzahlrechnungen.

Also Standard immer Integer nehmen, und in speziellen Fällen nimmst du floats

Je nachdem. Logischerweise Integer und Float für Zahlen und Character für Zeichen, aber generell kann man sagen, dass man Integer für ganzzahlige Operationen mit +,-,* und für Laufvariabeln nehmen kann und Float für Operationen mit Kommazahlen, mit / oder Konstanten wie pi und e. Bei sehr grossen Zahlen ist der Datentyp Double oft vorzuziehen, gerade heutzutage, wo etwas Speicher für mehr Stabilität entbehrbar ist.

Woher ich das weiß:Berufserfahrung – Programmierer