peace software
  Berndt Wischnewski  Richard-Wagner-Str. 49  10585 Berlin 
  Tel.: 030 - 3429075  FAX : 030 34704037  email: webmaster@peacesoftware.de  Ust-ID: DE135577379 

<= Previous

 

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.

 

<= Previous











Die Klassiker von Kerningham & Ritchie sowie Bjarne Stroustrup: