Sonntag, 25. November 2012

Primitive Datentypen - Variablen - Part 1

Hallo zusammen und herzlich willkommen zu einem neuen Post!
Heute geht es um eine sehr wichtige Sache in C# ohne die kein Programm laufen würde, nämlich die primitiven Datentypen, wie sie sich nennen.
In (fast) allen Programmen muss der Benutzer Werte eingeben, die später oder gleich verarbeitet, manipuliert, ausgegeben und verändert werden.
Beispiel: Ihr schreibt ein Programm, mit Hilfe dessen der Benutzer eine Software kaufen muss. Er muss dafür seinen Namen, sein Alter und seine Kontonummer angeben. Diese Daten werden sofort wieder ausgegeben, da der Benutzer ja sehen muss, was er gerade schreibt. Danach werden die Daten per Internet an eure oder eine andere Firma geschickt, die sie überprüft und verarbeitet, bevor sie die Zahlungsdaten an die Bank weiterschickt, die dann den gewünschten Geldbetrag überweist. Die vom Benutzer eingegebenen Daten müssen also für die Programmlaufzeit gespeichert werden. Das geschieht mit Variablen, die letztendlich immer aus den primitiven Datentypen bestehen. Die Daten werden im Arbeitsspeicher (RAM) des Computers gespeichert (Was ist Arbeitsspeicher oder RAM?).

In C# gibt es verschiedene primitive Datentypen (Grunddatentypen, also keine Steinzeitdatentypen oder ähnliches), die verschiedene Werte speichern können. Wir haben im letzten Post z.B. schon den String-Datentyp verwendet ("Hello World!"), der Zeichenketten speichert. Ein weiterer wichtiger Datentyp ist z.B. der Integer (in C# heißt die Abkürzung/das Synonym "int"), der nur ganzzahlige Werte zwischen -2147483648 bis 2147483647 speichern kann. Die nachfolgende Tabelle zeigt die verschiedenen primitiven Datentypen:

Datentyp
Abkürzung
Beschreibung
Wertebereich
Größe in Bits
Beispiel
Int32
int
Speichert ganze Zahlen im mittleren Wertebereich
-2.147.483.648 bis 2.147.483.647
32
int alter;
alter = 14;
Int64
long
Speichert ganze Zahlen im großen Wertebereich
-9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807
64
long staatsschulden;
staatsschulden = 2.111.342.807.600;
Int16
short
Speichert ganze Zahlen im kleinen Wertebereich
-32.768 bis 32.767
16
short keineAhnunWas;
keineAhnungWas = -2;
Byte
byte
Speichert natürliche Zahlen mit sehr kleinem Wertebereich
0 bis 255
8
byte rot;
rot = 72;
SByte
sbyte
Speichert ganze Zahlen mit sehr kleinem Wertebereich
-128 bis 127
8
sbyte noName;
noName = -23;
Single
float
Speichert Gleitkommazahlen mit einfacher Genauigkeit
±1,5 × 10-45 bis ±3,4 × 1038 (Genauigkeit: 7 Stellen)
32
float geldBetrag;
geldBetrag = 2.5f;
Double
double
Speichert Gleitkommazahlen doppelter Genauigkeit
±5,0 × 10−324 bis ±1,7 × 10308 (Genauigkeit: 15-16 Stellen)
64
double trouble;
trouble = 0.43412312;
Decimal
decimal
28 signifikante Stellen
±1,0 × 10-28 bis ±7,9 × 1028
128
decimal umrechnungsBetrag = 0.232323421566235m;
String
string
Zeichenfolge
16 bit je Zeichen
---
string name; name = Julian;
Char
char
Einzelzeichen
0 bis 216-1
16
char zeichen;
zeichen = 'A';
Boolean
bool
Boolescher Wert
true oder false
8
bool csharpIstCool;
csharpIstCool = true;

Über die hier genannten Datentypen hinaus gibt es noch weitere, wie z. B. uint, der Werte zwischen 0 und 4294967295 speichern kann, also ein int ohne den negativen, dafür mit doppeltem positiven Speicherbereich ist. Die Verwendung dieser Datentypen sollten jedoch nach Möglichkeit umgangen werden, da bei Übertragung des C#-Programmcodes in den Programmcode einer anderen .NET Framework-Sprache Kompatiblitätsprobleme auftreten können. Aber auch von diesen Datentypen eine Tabelle:

Datentyp
Abkürzung
Beschreibung
Wertebereich
Größe in Bits
Beispiel
UInt32
Uint
Speichert natürliche Zahlen im mittleren Wertebereich
0 bis 4.294.967.295
32
int alter;
alter = 14;
UInt64
Ulong
Speichert natüliche Zahlen im großen Wertebereich
0 bis 18.446.744.073.709.551.615
64
long staatsschulden;
staatsschulden = 2.111.342.807.600;
UInt16
Ushort
Speichert natürliche Zahlen im kleinen Wertebereich
0 bis 65.535
16
short keineAhnunWas;
keineAhnungWas = -2;

Um uns die Welt der Variablen besser vorstellen zu können, stellen wir uns folgendes vor: Wir haben ein Lagerhaus mit einer bestimmten Größe. Dieses Lagerhaus ist der Arbeitsspeicher des Computers. In diesem Lagerhaus stehen natürlich Kisten. Es gibt verschiedene Arten von Kisten, die jeweils nur eine Art von Gut enthalten können. Zum Beispiel dürfen in Lebensmittelkisten natürlich keine Chemikalien aufbewahrt werden. Diese Arten von Kisten entsprechen den Datentypen in C#. Außerdem hat jede Kistenart eine festgelegte Größe, sodass auch nur eine bestimmte Anzahl von Gütern in einer Kiste gelagert werden können. Diese Vorstellung wird uns gleich noch einmal begegnen.

Jetzt fangen wir mal an, die Variablen zu nutzen. Dazu erstellen wir wieder ein neues Konsolenprojekt im Visual Studio. Zuerst muss der Computer bzw. der Compiler (das ist die "Maschine", die unseren C#-Code in Computersprache übersetzt, nähere Infos hier) wissen, von welchem Typ die Kiste ist. In diesem Beispiel nehmen wir einfach mal einen int. Das schreiben wir jetzt einfach mal in den Programmcode, der danach folgendermaßen aussieht:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace PrimitiveDatentypen
{
    class Program
    {
        static void Main(string[] args)
        {
            int
        }
    }
}

Nun weiß der Compiler schon einmal, welchen Kistentyp er erstellen soll und wie viel Platz dafür im Lagerhaus verbraucht wird. Damit wir die Kiste aber später auch wieder auffinden können, muss sie eindeutig beschriftet werden. Dazu vergeben wir einfach einen beliebigen Namen. Bei der Namensgebung gelten allerdings folgende Einschränkungen:
  1. Der Variablenname muss im aktuellen Kontext eindeutig definiert sein, d.h., dass nicht derselbe Name zweimal vergeben werden kann (Dazu in einem späteren Post noch mehr)
  2. Der Variablenname darf nicht den folgenden Wörtern entsprechen, da diese für C# reserviert sind (die sog. Schlüsselwörter, die wir nach und nach kennen lernen werden):

new
as
out
try
for
if
ref
in
int
do
is
 
 

Außerdem sollten die Variablennamen nicht mit folgenden Worten übereinstimmen, da diese kontextabhängig auch für C# reserviert sind:

 
Sonst sind fast alle Variablennamen erlaubt, die nicht erlaubten werden auch von Visual Studio gemeldet.
 
Außerdem gibt es folgende Richtlinie: Falls der Variablenname nur aus einem Buchstaben/Wort besteht, so schreibt man ihn klein. Falls er aus mehreren Wörtern besteht, schreibt man das erste Wort klein, die darauffolgenden groß, also z. B. "diesIstEineVariable".
 
Wir nennen unsere Beispielvariable einfach mal, einfallsreich, wie wir sind, "zahl1". Jetzt sieht unsere Codezeile wie folgt aus:
 
int zahl1
 
Doch Visual Studio meckert mit der Fehlermeldung "; erwartet", denn auch das Erstellen einer Variablen ist ein Befehl, also das noch hinzufügen!
 
 
Was haben wir jetzt mit der Codezeile
 
int zahl1;
 
bewirkt?
Wir haben dem Compiler angewiesen eine Kiste im Lagerhaus aufzustellen, die eine Größe von 32 bit hat und vom Typ int ist, also in dieser Kiste nur ganze Zahlen innerhalb eines bestimmten Wertebereiches gelagert werden dürfen. Damit die Kiste später wieder für Aktionen wie Neubefüllung, Veränderung der in ihr enthaltenen Werte, etc. auffindbar ist haben wir sie beschriftet, in unserem Fall mit dem Namen "zahl 1". Den Vorgang nennt man Deklaration (auf Deutsch "Erklärung").
 
Um nun die Kiste zu füllen müssen wir dem Compiler erst sagen, mit was. Dazu schreiben wir nach der Deklaration folgende Codezeile, um der Variablen zahl1 vom Typ int einen Wert von 14 zuzuweisen:
 
zahl1 = 14;
 
Mit einem einfachen Gleichheitszeichen weisen wir der Variablen den Wert 14 zu, fast so, wie man es aus der Mathematik kennt. Auch das ist eine Anweisung, also ein Semikolon nicht vergessen! Das "Befüllen" einer Variablen nennt man Initialisierung. Nach der ersten Initialisierung kann auch eine 2., 3., ... kommen.
 
Man kann auch die Deklaration und die Initialisierung in eine Codezeile packen:
 
int zahl1 = 14;
 
Das sieht zwar nicht gerade nach viel Codeeinspaarung aus, ist es aber, wenn man bedenkt, dass ein Programm mehrere Millionen Codezeilen enthalten kann!
 
Jetzt wollen wir die Variable aber auch mal sinnvoll zum Rechnen verwenden. Dazu nehmen wir die obige Variable, geben ihren Wert aus, addieren dann 2 dazu und geben die neue Zahl aus:
 
int zahl1 = 14;
Console.WriteLine(zahl1);
zahl1 = zahl1 + 2;
Console.WriteLine(zahl1);
Console.ReadKey();
 
Zuerst wird die Variable "zahl1" vom Typ int deklariert und gleich mit dem Wert 14 initialisiert.
Dann wird dieser Wert auf der Konsole ausgegeben.
Jetzt kommt ein Ausdruck, bei dem sich jeder Mathematiker mit schmerzverzerrtem Gesicht krümmt: zahl1 = zahl1 + 2; Wie kann denn bitte "zahl1" gleich "zahl1 + 2" sein. Tja, das ist Informatik und keine Mathematik. Was da passiert ist ganz einfach: Man weißt der Variablen "zahl1" ihren ursprünglichen Wert + 2 zu. Dies ist nur möglich, da der Ausdruck von rechts nach links abgearbeitet wird.
Um das neue Ergebnis auszugeben ist die Wiederholung des Befehls "Console.WriteLine(zahl1);" nötig.
Damit das Programm sich dann nicht sofort schließt, folgt noch der Befehl "Console.ReadKey();".
 
Bei einem erfolgreichem Programmlauf erscheint auf der Konsole folgende Ausgabe:
 
14
16
 
Da die Entwickler der Sprache C# wissen, dass Informatiker für ihre Zeit bessere Verwendung haben, als unnötig viel Code zu schreiben, kann man den Ausdruck "zahl1 = zahl1 + 2;" noch verkürzen in "zahl1 += 2;". Wenn den Wert einer Variablen nur um 1 erhöhen will, so kann man auch schreiben "zahl1++;", um den Wert um 1 zu senken genügt "zahl1--;". Das sind die sog. Inkrement- und Dekrementoperatoren, die uns später erneut begegnen werden.
 
An dieser Stelle beende ich diesen Post, da es sinnvoll ist, vor der Fortsetzung noch eine Sache zu erlernen.
 
Bis dahin,
Julian
 
 

 
 

1 Kommentar: