Zu den Grundlagen der C Programmierung gehören auch die Kenntnis der einzelnen Datentypen. Datentypen sind, wie der Name schon vermuten lässt, Arten von Variablen, in denen Sie Daten speichern können, um zu einem späteren Zeitpunkt wieder darauf zurückzugreifen.C C++ C/C++ Datentypen Variablen int long short char float double unsigned signed Datentypen und Variablen - int long short char float double unsigned signed Kapitel 8: Datentypen und Variablen

In diesem Kapitel erfahren Sie alles zu den einzelnen Datentypen in C, ohne die sich wohl kaum ein Programm realisieren lassen würde.


Zu den Grundlagen der C-Programmierung gehört auch die Kenntnis der einzelnen Datentypen. Datentypen sind, wie der Name schon vermuten lässt, Arten von Variablen, in denen Sie Daten speichern können, um zu einem späteren Zeitpunkt wieder darauf zurückzugreifen. Diese Variablen bestehen aus zwei Teilen: dem Datentyp, der eine bestimmte Menge Arbeitsspeicher zugewiesen bekommt, und dem Namen der Variable, mit dem dieser Datentyp im Programm angesprochen werden kann.

8.1. Der Datentyp int (Integer)            zurück  Ein Kapitel tiefer  zum Inhaltsverzeichnis

Der Datentyp int muss, gemäß ANSI C, mindestens eine Größe von zwei Byte aufweisen. Mit diesen zwei Bytes lässt sich ein Zahlenraum von -32768 bis +32767 beschreiben. Mit dem Datentyp int lassen sich nur Ganzzahlen darstellen. Die Abkürzung int steht für Integer.

Hier kommen Sie auch gleich in Berührung mit betriebssystemspezifischen Eigenheiten. Auf 16-Bit-Systemen mag das eben Gesagte zutreffen. Dort ist ein Integer (int) auch wirklich zwei Bytes groß. Manch einer wird aber sagen: 16-Bit-Systeme sind doch schon bald Schnee von gestern und sind eigentlich nur noch für MS-DOS und Windows 3.1 Compiler relevant. Es sollte aber bedacht werden, dass es noch andere Programmierplattformen neben Linux und MS-Windows gibt!

Linux, Windows (ab Windows 95) und Macintosh sind alles schon Betriebssysteme auf 32-Bit-Basis. 32 Bit entsprechen vier Byte. Somit erstreckt sich der Zahlenraum auf 32-Bit-Systemen von -2147483648 bis +2147483647. Diese 32 Bit beziehen sich auf die WORD-Größe der CPU. Und die normale WORD-Größe von Pentium- und Athlon-Prozessoren beträgt zurzeit 32 Bit. In nicht mehr ferner Zukunft werden wohl aber 64 Bit-Prozessoren auf dem Massenmarkt erscheinen.

Damit gibt es auf solchen Systemen (32 Bit) auch keinen Unterschied mehr zwischen der Größe des Datentyps int und des Datentyps long (Erklärung folgt gleich). Hierzu ein kurzer Überblick über den Datentyp int und seinen Wertebereich auf den verschiedenen Systemen:

System Name Größe Wertebereich Formatzeichen
ANSI C int 2 Byte -32768
+32767
%d oder %i
IBM PC MS-DOS und Win3.1 int 2 Byte -32768
+32767
%d oder %i
Macintosh Metrowerks CW int 4 Byte -2147483648
+2147483647
%d oder %i
Win98/2000/NT/XP int 4 Byte -2147483648
+2147483647
%d oder %i
Linux int 4 Byte -2147483648
+2147483647
%d oder %i

Tabelle 8.1: Datentyp int auf verschiedenen Plattformen

Wenn Sie sichergehen wollen, welchen Wertebereich der Datentyp int auf einem System hat, so kann dies mit folgendem Listing herausgefunden werden:

#include <stdio.h>
#include <limits.h>   /* INT_MIN und INT_MAX */

int main()
{
   printf("int Größe : %d Byte\n",sizeof(int));
   printf("Wertebereich von %d bis %d\n",INT_MIN,INT_MAX);
   return 0;
}

Die Konstanten INT_MIN und INT_MAX sind in der Headerdatei <limits.h> mit den Werten deklariert, die der Datentyp int auf Ihrem System besitzt.

8.2. Variablen deklarieren            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Bevor Sie Variablen verwenden können, müssen diese deklariert sein. Die Syntax einer solchen Deklaration sieht wie folgt aus:

typ name;

Der typ der Variablen gibt vor, wie viel Speicherplatz diese Variable auf dem System belegt. Der name ist der Bezeichner, mit dem Sie auf diese Variable im Programm zugreifen können. Dieser name muss innerhalb eines Anweisungsblocks eindeutig sein. Außerdem sollte dieser Name selbsterklärend gewählt werden.

Wie Sie Datentypen in der Praxis deklarieren und mit Werten initialisieren können, soll jetzt grundsätzlich anhand des Datentyps int erläutert werden. Für andere Datentypen, die noch behandelt werden, gilt dies entsprechend. Ein Listing dazu:

#include <stdio.h>

int main()
{
   int a; /*Deklaration*/
   int b;
   int c;
   a=5;    /*Initialisieren*/
   b=100;
   c=12345;
   printf("Wert von int a=%d ,b=%d, c=%d\n",a,b,c);
   return 0;
}

Hier werden drei int-Variablen mit den Namen a, b und c deklariert. Die Auswahl der Namen bleibt dabei Ihnen überlassen. In kleinen Programmbeispielen ist die Verwendung so genannter sprechender Namen für Variablen nicht unbedingt erforderlich, dennoch empfehle ich Ihnen aussagekräftige Namen (z.B. ZuFallsZahl, statt einfach nur z) zu verwenden. Damit behalten Sie bei größeren Programmen den Überblick.

Hier bekommt a den Wert 5, b den Wert 100 und c den Wert 12345 zugewiesen. Die Zuweisung eines Werts wird das Initialisieren einer Variable genannt. Den Wert einer Variablen übergibt man mit dem =-Operator (wird auch Zuweisungsoperator genannt).

Achtung: Um Irritationen zu vermeiden, soll der Unterschied der Begriffe "Deklaration" und "Definition" erwähnt werden. Häufig hat es den Anschein, als bedeuteten beide dasselbe. Dies trifft jedoch nicht zu. Erst wenn bei einer Variablen-Deklaration eine Initialisierung vorgenommen wird, handelt es sich um eine Definition.

Folgende Schreibweisen sind dabei erlaubt:

int wert = 5;                 /* wert=5 */
int wert1 = 10, wert2 = 20;   /* wert1=10 ,wert2=20 */

/* wert1=nicht initialisiert, wert2=33 */
int wert1, wert2=33;

int wert1;
int wert2=wert1=10;         /* wert1=10, wert2=10 */

Jetzt folgt die Beschreibung der Ausgabe mit printf(). printf("Der Wert von int a= "bis hierhin nichts Neues" %d "das Prozentzeichen ist ein Formatzeichen". Der Compiler sieht jetzt nach, um welches Format es sich dabei handelt. Im Beispiel ist es das d (für dezimal). Sie können auch das Formatzeichen %i anstatt %d benutzen. Für einige ist das leichter zu verstehen, da das i für Integer steht. Hiermit wird also eine Ganzzahl (int) ausgegeben.

Hinter dem Ende des Hochkommatas befindet sich jetzt der Variablen-Name a. Damit wird der Wert von int a an der Position ausgegeben, an der sich das Formatzeichen %d befindet. Gleiches geschieht mit den anderen beiden int-Werten für b und c.

Abbildung 8.1: Der Ablauf der Funktion printf()
Abbildung 8.1: Der Ablauf der Funktion printf()

Die Initialisierung dieser Werte kann aber auch noch anders bewerkstelligt werden:

#include <stdio.h>

int main()
{
   int a=5;
   int b=100, c=12345;
   printf("Wert von int a=%d ,b=%d, c=%d\n",a,b,c);
   return 0;
}

Wie Sie hier sehen, kann die Wertzuweisung schon während der Deklaration vorgenommen werden. Es können auch alle Werte auf einmal zugewiesen werden, wie bei int b und int c geschehen. Die Werte müssen mit einem Komma getrennt werden.

Wenn eine Variable nicht mit einem Wert initialisiert wurde und Sie diese dennoch ausgeben, ist die Ausgabe des Werts undefiniert. Das heißt, es ist nicht vorhersehbar, welcher Wert ausgegeben wird.

8.2.1 Erlaubte Bezeichner
Mit dem Begriff "Bezeichner" werden Namen für Variablen, Funktionen, Datentypen und Makros zusammengefasst. Damit Sie bei der Namensvergabe von Variablen oder (später) Funktionen keine Probleme bekommen, müssen Sie bei deren Angabe folgende Regeln beachten:

Die reservierten Schlüsselworte in C dürfen logischerweise auch nicht als Bezeichner verwendet werden. Hier ein Überblick der reservierten Schlüsselwörter in C:

auto  break  case  char  complex  const  continue  default
do  double  else  enum  extern  float  for  goto
if  imaginary  inline  int  long  register  restrict  return
short  signed  sizeof  static  struct  switch  typedef  union
unsigned  void  volatile  while

Die Schlüsselworte, die hier fett dargestellt wurden, sind erst bei den neueren Compilern (C99) vorhanden. Aber es empfiehlt sich, diese dennoch nicht zu verwenden, falls sie bei Ihrem Compiler noch nicht implementiert sind.

8.3. C versus C++ bei der Deklaration von Variablen            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

C++ lässt sich grob als Erweiterung von C ansehen. Daher ist so manches, was in C++ erlaubt ist, in C nicht erlaubt. In C muss die Deklaration der Variablen zu Beginn eines Anweisungsblocks geschrieben werden, bei C++ hingegen nicht. Hierzu ein kommentierter Quellcode:

#include <stdio.h>

int main()
{
   printf("Hallo Welt\n");
   int i;             /*Fehler in C, ok in C++*/

   scanf("%d",&i);
   for(int x=0; x < i; x++)  /*Fehler in C, ok in C++*/
      {
         /*Ok in C und C++, da am Anfang von Anweisungsblock*/
         int x=2;
         printf("%d*%d=%d\n",x,i,x*i);
      }
   return 0;
}

Heutzutage gibt es kaum noch reine C-Compiler. Ich erwähne dies jedoch für den Fall, dass Sie es irgendwann dennoch mit einem reinen C-Compiler zu tun haben und dieser dann Variablen-Deklarationen im C++-Stil nicht versteht.

Hinweis
 

Im C99-Standard muss die Deklaration einer Variablen nicht mehr am Anfang eines Anweisungsblocks erfolgen.

8.4. Der Datentyp long            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Der Datentyp long entspricht wie der Datentyp int auch einer Ganzzahlvariable. Bei 16-Bit-Systemen hat dieser Typ einen größeren Zahlenbereich und verbraucht somit auch mehr Speicherplatz als der Datentyp int. Hier ein Vergleich mit dem Datentyp int auf einem 16-Bit-System:

Name Größe Wertebereich Formatzeichen
int 2 Byte -32768
+32767
%d oder %i
long 4 Byte -2147483648
+2147483647
%ld oder %li

Tabelle 8.2: Der Datentyp long im Vergleich mit int (16-Bit-Systemen)

Den Datentyp long können Sie benutzen, wenn Berechnung mit größeren Zahlen durchführt werden. Das Formatzeichen ist hier %ld oder %li, von "long dezimal" bzw. "long integer". long ist also nichts anderes als ein größeres int, und genauso kann es auch benutzt werden. Mit dem Datentyp long kann der Datentyp int auf 16-Bit-Systemen modifiziert werden, sodass der Wertebereich von int vergrößert wird:

long int a;

Jetzt stellt sich die Frage, welche Daseinsberechtigung hat der Datentyp long dann eigentlich noch auf 32-Bit-Systemen? long hat ja auf diesen Systemen dieselbe Größe und denselben Wertebereich wie der Datentyp int. Die Antwort könnte lauten: aus Kompatibilitätsgründen. Damit alte Programme, die für 16-Bit-Rechner geschrieben wurden, auch noch auf einem 32-Bit-Rechner laufen bzw. übersetzt werden können. Das gilt auch für den umgekehrten Fall. Dies sollten Sie beachten, wenn Sie ein Programm für ein 32-Bit-System geschrieben haben und es dann auf ein 16-Bit-System portierten wollen. In diesem Fall ist es empfehlenswert, den Datentypen long zu verwenden. Sollte bei einem Programm auf dem 16-Bit-Rechner eine Zahl, z.B. "1000000", vorkommen, und es wurde der Datentyp int verwendet, wird das Programm mit falschen Werten rechnen und möglicherweise völlig unvorhergesehene Reaktionen zeigen.

Hinweis
 

Neu (C99-Standard) ist der erweiterte long-Datentyp. long long ist ein 64 Bit (8 Byte) breiter Datentyp, der einen Wertebereich von -9.223.372.036.854.755.807 bis +9.223.372.036.854.755.807 darstellen kann.

8.5. Der Datentyp short            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Nach der Betrachtung der Typen int und long stellt sich die Frage: Was ist, wenn ich gar keine so große Ganzzahl benötige? Beziehungsweise, was ist, wenn das Programm nicht so viel Speicherplatz verbrauchen darf? Dafür gibt es den Datentyp short, der genauso verwendet wird wie schon int und long. Hier die Angaben zu short:

Name Größe Wertebereich Formatzeichen
short 2 Byte -32768
+32767
%d oder %i

Tabelle 8.3: Der Datentyp short

Achtung
 

Wollen Sie Programme schreiben, die auf 16-Bit- und 32-Bit-Systemen richtig laufen sollen, verwenden Sie für Ganzzahltypen die Typen long und short und verzichten dabei ganz auf den Datentyp int, da dieser wie gezeigt unterschiedliche Zahlenräume auf verschiedenen Systemen abdeckt.

8.6. Die Gleitpunkttypen float und double            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Jetzt zu den Gleitpunkttypen (Floatingpoint). Mit ihnen wird es möglich, genauere Berechnungen mit Nachkommastellen auszuführen. Hier wieder zuerst eine kleine Übersicht:

Name Größe Wertebereich Genauigkeit Formatzeichen
float 4 Byte 1.2E-38
3.4E+38
6-stellig %f
double 8 Byte 2.3E-308
1.7E+308
15-stellig %lf
long double 10 Byte 3.4E-4932
1.1E+4932
19-stellig %lf

Tabelle 8.4: Datentypen zur Darstellung von Gleitpunktzahlen

Angewendet wird dieser Datentyp genauso wie int und alle andere Datentypen, die Sie bereits kennen. Hierzu eine kurze Erklärung, warum es Gleitpunkttyp und nicht Gleitkommatyp heißt. Dies liegt daran, dass die Programmiersprache C in den USA entwickelt wurde. Und dort wird anstatt eines Kommas zwischen den Zahlen ein Punkt verwendet (man spricht von floating point variables):

float a=1,5;   /* FALSCH */
float b=1.5;   /* RICHTIG */

Das Komma verwenden die US-Amerikaner wiederum genauso wie Europäer den Punkt bei größeren Zahlen. Folgendes Beispiel schreiben wir (Europäer) so:

1.234.567  

Und die US-Amerikaner schreiben dies wiederum so:

1,234,567

Dazu ein Beispiel. Es wird ein Programm geschrieben, welches die Fläche eines Rechtecks berechnet.

#include <stdio.h>

int main()
{
   /* Deklaration */
   float flaeche, l, b;

   printf("Berechnung der Flaeche eines Rechtecks\n");
   /* Werte einlesen */
   printf("Laenge des Rechtecks: ");
   scanf("%f",&l);
   printf("Breite des Rechtecks: ");
   scanf("%f",&b);
   /* Fläche berechnen */
   flaeche = l * b;
   printf("Flaeche des Rechtecks betraegt : %f\n",flaeche);
   return 0;
}

Bei diesem Listing wird der Anwender nach der Länge und der Breite einer rechteckigen Fläche gefragt. Diese Gleitpunktzahl wird mit Hilfe von scanf() eingelesen und an die Adressen der Variablen l und b übergeben. Anschließend wird dieser Wert zur Berechnung verwendet. Das Ergebnis wird am Schluss des Programms auf dem Bildschirm ausgegeben.

Beachten Sie im Zusammenhang mit Gleitpunktzahlen auch Folgendes: Wenn Sie zwei Verschiedene Variablen z.B. int und float miteinander durch Operatoren verknüpfen, erhalten Sie das Ergebnis vom genaueren Datentyp dieser beiden Variablen zurück. Ein Beispiel:

#include <stdio.h>

int main()
{
   float f;
   int i;

   f=5.0;
   i=2;

   printf("%f\n",f/i); /*Ergebnis = 2.500000*/
   return 0;
}

Die Ausgabe des Programms ist "2.500000", weil der genauere der beiden Datentypen hier vom Typ float ist.

8.6.1 Gleitpunkttypen im Detail
Bei Gleitpunkttypen wird auch von Zahlen mit gebrochenem Anteil (reelle Zahlen) gesprochen. Der C-Standard schreibt hierbei nicht vor, wie die interne Darstellung von reellen Gleitpunktzahlen erfolgen muss. Dies ist abhängig von den Entwicklern der Compiler. Meistens wird aber der IEEE-Standard 754 verwendet (IEEE = Institute of Electrical and Electronics Engineers). In der Regel kann es dem Programmierer egal sein, wie Gleitpunktzahlen auf seinem System dargestellt werden. Trotzdem, für den interessierten Programmierer hier eine kurze Erklärung der internen Darstellung von Gleitpunktzahlen, ohne sich zu sehr in die Details zu verfangen.

Gleitpunktzahlen werden halb logarithmisch dargestellt, das heißt, die Darstellung einer reellen Gleitpunktzahl basiert auf einer Zerteilung in ein Vorzeichen, eine Mantisse und einen Exponenten zur Basis 2. Für echte Mathematiker sei gesagt, dass der Begriff "Mantisse" hier nichts mit einer Mantisse eines Logarithmus gemeinsam hat.

Die Genauigkeit nach dem Komma der Gleitpunktzahl hängt von der Anzahl der Bits ab, die der entsprechende reelle Datentyp in seiner Mantisse speichern kann. Der Wertebereich hingegen wird durch die Anzahl der Bits für den Exponenten festgelegt.

Hierzu folgen die Speicherbelegungen der einzelnen reellen Gleitpunktzahlen im IEEE-Format.

8.6.2 float im Detail
float ist eine 32-Bit-Zahl. Diese 32 Bit teilen sich folgendermaßen auf:

Abbildung 8.2: float im Detail

Abbildung 8.2: float im Detail

8.6.3 double im Detail
Beim Datentyp double ist es ähnlich wie bei float. double ist eine 64 Bit Zahl mit doppelter Genauigkeit. double ist folgendermaßen aufgeteilt:

Abbildung 8.3: double im Detail

Abbildung 8.3: double im Detail

8.6.4 long double
Wird dem Datentyp double das Schlüsselwort long vorangestellt, erhalten Sie eine 80 Bit Zahl mit einer noch höheren Genauigkeit.

Wenn Sie long double mit dem sizeof-Operator auf seine Speichergröße in Bytes überprüft haben, dürften Sie sicherlich verwundert sein, dass der Datentyp auf 32-Bit-Systemen 12 Bytes beansprucht. Auf einem 32-Bit-System werden dazu einfach zwei Füllbytes angefügt. Auf 16-Bit-Systemen beansprucht long double weiterhin 10 Bytes Speicher. Auf einer HP-UX Maschine hingegen benötigt long double gar 16 Bytes an Speicher. Dabei werden aber alle 128 Bits genutzt, und somit lässt sich eine Genauigkeit von 33 Stellen anzeigen.

8.6.5 Einiges zu n-stelliger Genauigkeit
Eine Fließkommazahl mit 6-stelliger Genauigkeit wie float kann sechs Dezimalstellen nicht immer korrekt unterscheiden. Wenn beispielsweise die Zahl vor dem Komma (z.B. "1234,1234") bereits vier Stellen besitzt, so kann sie nach dem Komma nur noch zwei Stellen unterscheiden. Somit wären die Gleitpunktzahlen 1234,12345 und 1234,123999 als float-Zahlen für den Computer nicht voneinander unterscheidbar. Mit 6-stelliger Genauigkeit sind die signifikanten Stellen von links nach rechts gemeint. Der Typ float ist also ungeeignet für kaufmännische und genaue wissenschaftliche Berechnungen. Dazu folgendes Beispiel:

#include <stdio.h>

int main()
{
   float x=1.1234;
   float dollar=100000.12;
   float end_float;

   double y=1.1234;
   double DOLLAR=100000.12;
   double end_double;

   printf("%f Euro mit float\n",end_float=dollar*x);
   printf("%f Euro mit double\n",end_double=DOLLAR*y);
   return 0;
}

Hier werden zwei verschiedene Ergebnisse zurückgegeben. Die Differenz mag minimal sein, doch bei Börsenberechnungen könnte eine solche Ungenauigkeit durchaus Millionen von Euro kosten, und in der Astronomie wäre der Mond wohl heute noch nicht erreicht.

Abbildung 8.4: Darstellung von Fließkommazahlen mit double und float
Abbildung 8.4: Darstellung von Fließkommazahlen mit double und float

float ist nach sechs Dezimalstellen am Ende. Mit double haben Sie dagegen die Möglichkeit, eine auf 15 Stellen genaue Zahl zu erhalten und mit long double eine 19-stellige.

Was ist zu tun, wenn diese Genauigkeit nicht ausreichen sollte? In diesem Fall müssen Sie sich nach so genannten Festkomma-Algorithmen umsehen. Denn Festkomma-Darstellungen wie die BCD-Arithmetik gibt es in C nicht.

Hinweis
 

BCD steht für Binary Coded Dezimals und bedeutet, dass die Zahlen nicht binär, sondern als Zeichen gespeichert werden. Bspw. wird der Wert 56 nicht wie gewöhnlich als Bitfolge 00111000 gespeichert, sondern als die Werte der Ziffern im jeweiligen Zeichensatz. In unserem Fall dem ASCII-Code-Zeichensatz. Und dabei hat das Zeichen "5" den Wert 53 und das Zeichen "6" den Wert 54. Somit ergibt dadurch folgende Bitstellung: 00110101 (53) 00110110 (54). Damit benötigt der Wert 53 allerdings 16 anstatt der möglichen 8 Bit. Für die Zahl 12345 hingegen benötigen Sie schon 40 Bits. Es wird zwar erheblich mehr Speicherplatz verwendet, doch wenn Sie nur die Grundrechenarten für eine Ziffer implementieren, können Sie mit dieser Methode im Prinzip unendlich lange Zahlen bearbeiten. Es gibt keinen Genauigkeitsverlust.



Hinweis
 

Bei dem Listing oben wurde bei der formatierten Ausgabe für den Datentyp double %f verwendet, was übrigens bei der Ausgabe mit printf() nicht falsch ist. Verwenden Sie hingegen scanf(), kommt es zu Problemen. scanf() benötigt für double nämlich %lf. Dies liegt daran, dass Argumente in variablen Argumentlisten in C den Default Promotion unterliegen.

8.7. Nummerische Gleitpunktprobleme            zurück  Ein Kapitel höher  zum Inhaltsverzeichnis

Vorsicht ist geboten vor Ungenauigkeiten durch die binäre Darstellung von Gleitkommazahlen. Reelle Zahlen können im Gleitkommaformat nicht immer exakt dargestellt werden. Das liegt daran, dass die Gleitkommasemantik so implementiert ist, wie es der Prozessor berechnet. Würde man dafür eine extra Funktion für den Compiler schreiben, wäre die Berechnungsdauer systemabhängig. Würde die Berechnung beispielsweise bei einem Pentiumprozessor optimal ablaufen, könnte diese bei einem Athlon wiederum katastrophale Laufzeiten haben. Dadurch kann es bei der Berechnung von arithmetischen Ausdrücken zu Ungenauigkeiten kommen (wie weiter oben schon gezeigt wurde).

Achtung
 

Zahlen im Gleitkommaformat sollten nie auf Gleichheit überprüft werden!

Folgendes Programm wird in eine Endlosschleife laufen, da die Zahl 0.1 nie exakt dargestellt werden kann:

#include <stdio.h>

int main()
{
   float i=0.0;
   for (i=0.0; i != 1.0; i += 0.1)
     printf("%f",i);
   return(0);
}
Sicherer ist es, wenn Sie dieses Beispiel so überprüfen:
#include <stdio.h>

int main()
{
   float i=0.0;
   for (i=0.0; i<0.9999 || i>1.0001; i += 0.1)
     printf("%f",i);
   return(0);
}



Hinweis
 

Für den Fall, dass sich jemand näher mit der Gleitpunktdarstellung auf verschiedenen Systemen auseinander setzen will (muss) ein Link dazu: http://cch.loria.fr/documentation/IEEE754/numerical_comp_guide/index.html

Weiter mit: 8.8. Der Datentyp char          zum Inhaltsverzeichnis