C Kurs - Was Sie schon immer über
Variablen wissen wollten, jedoch nie zu fragen wagten
1. Was ist eigentlich
eine Variable
Den Begriff Variable habe ich schon mehrmals erwähnt, aber
noch nicht nicht erklärt. Dabei sind Variablen in fast allen Programmiersprachen
mit das wichtigste überhaupt. Im Prinzip ist eine Variable ein Stück
Speicherplatz, auf den über einen Namen zugegriffen werden kann. wenn in
meinem Programm steht:
int x;
bedeutet dies: Bitte lieber C-Compiler, reserviere mir im Hauptspeicher
meines Computers ein Stück Speicherplatz der Größe int
und lass mich auf diesem Speicher über den Namen x zugreifen.
int? int bedeutet integer
und integer bedeutet: eine ganze Zahl.Die Größe
des für int reservierten Speicherplatzes liegt jetzt fest. Dummerweise
ist sie nicht für alle C-Compiler gleich groß, auf alten 16-Bit Betriebssystemen
wie MS-DOS ist int 16-Bit, also 2 Byte groß, auf neueren
Compilern ist eine integer Variable 32-Bit, also 4 Byte groß.
Eine Integer Zahl hat ein Vorzeichen. Jetzt ein bisschen rechnen: eine 16-Bit
Integer kann demnach von -(2 hoch15) bist (+2 hoch 15) - 1 gehen (-32768 bis
32767), ein 32-Bit Integer liegt zwischen - (2 hoch 31) und (+2 hoch 31) -1
(-2147483648 bis 2147483647). Schwierig, also noch mal mit Abbildung:
Also noch mal: eine Variable ist ein Stück Speicherplatz in Ihrem Computer.
Wenn Sie in C eine Variable deklarieren, dann geben Sie zuerst den Typ
an, z.B. int. Damit legen Sie die Größe des Speichers für diese
Variable und die Art, wie dieser Speicher verwaltet werden soll fest. Danach
geben Sie der Variable einen Namen, siehe Namensregeln
im letzten Kapitel. Vom Typ der Variablen hängt ebenfalls ab wie der Computer
mit den darin enthaltenen Daten umgeht. Im Prinzip gibt es drei Typen mit mehreren
Variationen. Die drei Grundtypen sind:
- Character für Text,
- Integer für ganze Zahlen
- Floating Point für Rationale Zahlen(Komma-Zahlen)
Hier eine ausführliche Tabelle der vom C Compiler standardmäßig
zur Verfügung gestellten Datentypen. Wie schon gesagt, ist die Definition
von int nicht auf allen Compilern gleich, dargestellt wird die von neuerern
Compilern benutzte Art und Weise mit 32-Bit Integern.
2. Tabelle Grundtypen
von C Variablen
Type |
Bits / Bytes |
Inhalt |
Beschreibung |
char |
8 Bits / 1 Byte |
-128 bis 127
-2 hoch 7 bis (2 hoch 7) - 1 |
Character, Buchstabe, für Text |
unsigned char |
8 Bits / 1 Byte |
0 bis 255
0 bis (2 hoch 8) - 1 |
Character, Buchstabe, für Text,
Wert ohne Vorzeichen |
int |
32 Bits / 4 Bytes |
-2147483648 bis 2147483647
-(2 hoch 31) bis (2 hoch 31) - 1
|
ganze Zahl mit Vorzeichen |
unsigned int |
32 Bits / 4 Bytes |
0 bis 4294967295
0 bis (2 hoch 32) - 1 |
ganze Zahl ohne Vorzeichen |
short oder
short int |
16 Bits / 2 Bytes |
-32768 bis 32767-(2 hoch 15)
0 bis (2 hoch 15) - 1
|
ganze Zahl mit Vorzeichen |
unsigned short
oder
unsigned short int |
16 Bits / 2 Bytes |
0 bis 65535
0 bis (2 hoch 16) - 1 |
ganze Zahl ohne Vorzeichen |
long
oder
long int |
32 Bits / 4 Bytes |
-2147483648 bis 2147483647
-(2 hoch 31) bis (2 hoch 31) - 1
|
ganze Zahl mit Vorzeichen |
unsigned long
oder
unsigned long int |
32 Bits / 4 Bytes |
0 bis 4294967295
0 bis (2 hoch 32) - 1 |
ganze Zahl ohne Vorzeichen |
float |
32 Bits / 4 Bytes |
Etwa sechs Stellen Genauigkeit |
Rationale Zahl |
double |
64 Bits / 8 Bytes |
Etwa zwölf Stellen Genauigkeit |
Rationale Zahl |
long double |
128 Bits / 16 Bytes |
Etwa 24 Stellen Genauigkeit |
Rationale Zahl |
Was soll eigentlich immer dieses (2 hoch *) - 1 ??? Nun zum speichern einer
Zahl stehen z.B. 32 Bit zur Verfügung. Das heißt, es können
Zahlen von 1 bis 2 hoch 32 dort eingetragen werden. Will man die Null noch dazu
nehmen (und man will es), dann hat man eine Zahl weniger also (2 hoch 32) -
1. Und überhaupt 3 Bytes sind 24 Bits und machen zusammen einen Kasten
Bitburger.
Was passiert wenn ich größer werde, als der vom Variablentyp maximal
mögliche Wert, z.B.
long a, b, x;
a = 2147483600;
b = 2147483600;
x = a + b;
Nun das Ergebnis ist -96; es "läuft über". Im Hauptspeicher
werden halt nur Bits innerhalb des Speicherbereiches der Variablen addiert.
Was kann man da tun? 1) versuchen sich einen Datentyp zu suchen, bei dem alle
ganzen Zahlen nie größer werden, als maximal zulässig, meistens
klappt das. 2) überlegen ob man von long auf double
umstellen kann, diese werden immer richtig berechnet, hierbei verliert man unter
Umständen an Genauigkeit 3) man schreibt sich selber Funktionen, die dieses
Problem lösen.
Neben diesen standardmäßig immer vorhandenen Datentypen, lasse verschieden
Compilerhersteller noch verschiedene andere Typen zu, wie z.B. comp, BYTE, WORD
usw. Wenn es einem dies das Leben nicht unheimlich erleichtert, würde ich
sie aber nicht benutzen. Einen wichtigen gibt es aber noch: den Typ für
die bool'schen Variablen. Diese können nur zwei Werte
annehmen, nämlich wahr oder falsch. Dieser ist in Standard C leider nicht
enthalten und wird blöderweise von verschiedenen Compilern verschieden
implementiert. Der Type heißt dann: BOOL oder bool oder Boolean oder so.
Und die möglichen Werte sind dann: TRUE - FALSE oder true - false oder
so ähnlich. In der Beschreibung Ihres Compilers steht dies irgendwo. Wichtig:
Bool'sche Variablen sind immer so implementier, das false =
Null ist und alles andere als true angesehen wird.
3. kurz eingeschoben
: Kommentare
Kommentare sind da zu da, Ihr Programm zu kommentieren (toller
Satz). In Programmen mittlerer Größe ist es wichtig die Abläufe,
die Funktionen, die Variablen oder sonst was zu kommentieren. Und zwar damit
man selber oder andere, das Programm auch noch nach Jahren nachvollziehen kann.
Weiterhin benutzt man Kommentare auch häufig da zu, bestimmte Programmteile
oder Programmzeilen kurz auszukommentieren, um mal zu testen
wie das Programm denn ohne diesen Teil läuft.
Es gibt zwei Arten von Kommentaren:
- 1. alles was zwischen /* .. */ steht ist ein Kommentar
und wird vom Compiler nicht weiter beachtet. Dieser Kommentar läuft auch
über mehrere Zeilen.
- 2. alles was nach // bis zum Zeilenende steht ist ein Kommentar
Beispiel :
#include
<stdio.h>
/*
dieses Programm, hello.c, ist nur zu Testzwecken
gedacht
Programmierer: benwisch - peace software
10.1.2003
Online C-Kurs
*/
int main(void) // hier beginnt die main Funktion,
hier startet mein Programm
{
printf("hello world");
return 0;
}
4. Deklaration
von Variablen
Man darf Variablen gleichen Typs in einer Zeile deklarieren;
die Leerzeichen sind nur zur besseren Lesbarkeit eingefügt, sie dürfen
da stehen, müssen aber nicht:
int x, y,
z; // Deklaration von 3 Variablen des Typs int
Man
kann Variablen während der Deklaration gleich einen Wert zuweisen:
int x =
0, y, z = 123; // Deklaration von 3 Variablen des Typs int; x und
z wurde gleich ein Wert zugewiesen
Und man kann auch mehreren Variablen auf einmal einen Wert zuweisen:
int x, y,
z; // Deklaration von 3 Variablen des Typs int;
x = y = z = 123; // Alle drei Variablen, x , y und z, haben jetzt den Wert
123
Die Deklaration von Variablen in C kann an zwei Stellen erfolgen.
1. Innerhalb des Funktionsrumpfes direkt am Anfang der Funktion
vor der ersten ausführbaren Anweisung. Diese Variablen sind dann nur
lokal innerhalb der Funktion gültig. In C++, der objektorientierten
Erweiterung von C, müssen Variablen nicht am Anfang der Funktion deklariert
werden, sondern können an beliebiger Stelle der Funktion deklariert
werden. Ansonsten "sieht" eine Funktion nur die Variablen, die in
ihr deklariert wurden. Deklarieren zwei verschieden Funktionen jeweils eine
Variable mit dem Namen x, so legt der Compiler an verschieden Stellen im Hauptspeicher
Platz für jeweils das eine und das andere x an. Es ist also völlig ungefährlich,
in verschiedenen Funktionen den selben Variablennamen zu benutzen, die Funktion
"sieht" nur die eigenen Variablen, nicht die der anderen Funktionen.
2. Außerhalb einer Funktion, diese Variablen sind dann
global, d.h. jede beliebige Funktion "sieht" diese Variablen
dann.
Hier ein Beispiel :
#include <stdio.h>
float pi = 3.141592; //
globale Variable
int main(void)
{
float radius, kreis; // lokale Variablen
radius = 42.5;
kreis = radius * radius * pi;
return 0;
}
5. Global versus lokal
In einer der ersten Informatik Vorlesungen bekommt man erklärt,
dass globale Variablen böse sind. Das stimmt auch und zwar
wegen 1) Seiteneffekten; man benutzt in einer Funktion xxx
eine globale Variable, ruft in dieser Funktion eine andere Funktion abc auf,
die diese globale Variable wiederum verändert. Und schon hat man den Salat.
2) doppelte Namensgebung; in etwas umfangreicheren Programmen
fällt einem erstaunlich schnell der selbe Variablenname zweimal ein, liegt
meistens am Thema, z.B- thermoKoeff für Thermo Koeffizient und wenn es
dann einen zweiten Thermo Koeffizienten gibt, heißt die Variable dann
schnell genauso oder fast genauso. Also sollte man globale Variablen sparsam
benutzen und sich vorher überlegen ob man sie wirklich braucht. Meistens
kann man diese Variablen auch als Parameter übergeben. Anfänger benutzen
gerne global angelegte Variablen und scheuen sich davor, Variablen als Parameter
zu übergeben, deshalb hier gleich der Tip, gewöhnen Sie sich das gar
nicht erst an. Hier mal ein typisches Beispiel für diese beiden Fehler:
int franz, gans; //
globale Variablen
float thermoKoeff; // globale Variable
int main(void)
{
thermoKoeff = 123.456; // globaler Variablen
wird ein Wert zugewiesen
myFunction1(); // myFunction1 wird aufgerufen
return 0; // Hauptprogramm wird beendet
}
void myFunction1(void)
{
float thermokoeff; // neue Variable wird
deklariert, nur mit kleinem "k"
thermokoeff
= 456.789; // lokaler Variablen wird ein anderer Wert zugewiesen
gans = 42; // globaler Variablen "gans" wird
ein Wert zugewiesen
franz = myFunction2(thermoKoeff);
/*
myFunction2 wird aufgerufen, mit dem globalen "thermoKoeff",
nicht mit dem lokalen "thermokoeff"; Namensähnlichkeit
*/
franz = franz + gans;
/*
zu dem Funktionsergebnis "franz" wird die
globale Variable "gans" addiert, diese wurde jedoch von myFunction2
verändert
*/
}
int myFunction2(float
inputVariable)
{
gans = gans * inputVariable; // hier wird die
globale Variable "gans" verändert; Seiteneffekt
return gans;
}
Auf der anderen Seite ist es natürlich sinnvoll, Variablen die an hundert
Stellen im Programm benutzt werden, global anzulegen. Man muß dann halt
aufpassen... Die Regel heißt wohl, so wenig wie nötig.
6. statische
Variablen
Es tritt recht häufig der Fall ein, dass der Wert, den eine
Variable in einer Funktion angenommen hat, später beim nächsten Funktionsaufruf
noch mal benötigt wird. Wie löst man diesen Fall? Übergibt man
jedesmal diesen Wert? Das funktioniert nicht wenn die Funktion von verschiedenen
Stellen des Programms aus aufgerufen wird. Also doch wieder globale Variablen?
Nein, der liebe Gott, oder Kerningham & Ritchie, hat für diesen Fall
den Deklarationstyp static vorgesehen. Normalerweise "vergisst" eine
Funktion nach ihrer Beendigung alle ihre Variablen. Anders ausgedrückt,
der Compiler gibt den Speicherplatz, den er für diese Variablen angelegt
hatte, wieder frei. Wenn man eine Variable als static deklarier, sagt man dem
C-Compiler: lege dir diese Variable doch bitte gesondert ab und gebe den Speicherplatz
nach beenden der Funktion nicht wieder
frei. Hier kommt auch schon ein Beispiel:
#include <stdio.h>
int main(void)
{
function1();
function1();
function1();
return 0;
}
void function1(void)
{
static int statvar; // eine statische Variable
statvar = statvar + 100;
printf("%d\n", statvar); // formatierte Ausgabe von Variablen,
kommt später
mal
}
Ausgegeben wird:
100
200
300
der Wert den statvar hatte, wurde also beibehalten. Als Startwert haben statische
Variablen immer den Wert Null.
|